Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/corba.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/corba.tar.xz differ diff -Nru openjdk-8-8u232-b09/debian/changelog openjdk-8-8u242-b08/debian/changelog --- openjdk-8-8u232-b09/debian/changelog 2019-10-16 20:38:15.000000000 +0000 +++ openjdk-8-8u242-b08/debian/changelog 2020-01-17 23:41:21.000000000 +0000 @@ -1,12 +1,78 @@ -openjdk-8 (8u232-b09-0ubuntu1~18.04.1) bionic-security; urgency=medium +openjdk-8 (8u242-b08-0ubuntu3~18.04) bionic-security; urgency=medium - * Backport from Eoan. + * Backport from Focal. - -- Tiago Stürmer Daitx Wed, 16 Oct 2019 20:38:15 +0000 + -- Tiago Stürmer Daitx Fri, 17 Jan 2020 23:41:21 +0000 -openjdk-8 (8u232-b09-0ubuntu1.1) eoan-security; urgency=high +openjdk-8 (8u242-b08-0ubuntu3) focal; urgency=medium - * Update to OpenJDK 8u232-b09 (GA). Updated aarch32 to 8u232-b08. + * Sync packages with 8u242-b08: + * OpenJDK 8u242-b08 build (release). + - S8226352, CVE-2020-2590: Improve Kerberos interop capabilities + - S8228548, CVE-2020-2593: Normalize normalization for all + - S8224909, CVE-2020-2583: Unlink Set of LinkedHashSets + - S8229951, CVE-2020-2601: Better Ticket Granting Services + - S8231422, CVE-2020-2604: Better serial filter handling + - S8231795, CVE-2020-2659: Enhance datagram socket support + - S8234037, CVE-2020-2654: Improve Object Identifier Processing + - S8037550: Update RFC references in javadoc to RFC 5280 + - S8039438: Some tests depend on internal API sun.misc.IOUtils + - S8044500: Add kinit options and krb5.conf flags that allow users + to obtain renewable tickets and specify ticket lifetimes + - S8058290: JAAS Krb5LoginModule has suspect ticket-renewal logic, + relies on clockskew grace + - S8080835: Add blocking bulk read to sun.misc.IOUtils + - S8138978: Examine usages of sun.misc.IOUtils + - S8139206: Add InputStream readNBytes(int len) + - S8183591: Incorrect behavior when reading DER value with + Integer.MAX_VALUE length + - S8186576: KerberosTicket does not properly handle renewable + tickets at the end of their lifetime + - S8186831: Kerberos ignores PA-DATA with a non-null s2kparams + - S8186884: Test native KDC, Java krb5 lib, and native krb5 lib in + one test + - S8193832: Performance of InputStream.readAllBytes() could be improved + - S8196956: (ch) More channels cleanup + - S8201627: Kerberos sequence number issues + - S8215032: Support Kerberos cross-realm referrals (RFC 6806) + - S8225261: Better method resolutions + - S8225279: Better XRender interpolation + - S8226719: Kerberos login to Windows 2000 failed with "Inappropriate + type of checksum in message" + - S8227061: KDC.java test behaves incorrectly when AS-REQ contains a + PAData not PA-ENC-TS-ENC + - S8227381: GSS login fails with PREAUTH_FAILED + - S8227437: S4U2proxy cannot continue because server's TGT cannot be found + - S8227758: More valid PKIX processing + - S8227816: More Colorful ICC profiles + - S8230279: Improve Pack200 file reading + - S8230318: Better trust store usage + - S8230967: Improve Registry support of clients + - S8231129: More glyph images + - S8231139: Improved keystore support + - S8232381: add result NULL-checking to freetypeScaler.c + - S8232419: Improve Registry registration + - S8233944: Make KerberosPrincipal.KRB_NT_ENTERPRISE field package private + - S8235909: File.exists throws AccessControlException for invalid + paths when a SecurityManager is installed + - S8236983: [TESTBUG] Remove pointless catch block in + test/jdk/sun/security/util/DerValue/BadValue.java + - S8236984: Add compatibility wrapper for IOUtils.readFully + * Use the hotspot arch list to select between hotspot and zero as + the default VM for autopkgtests. This fixes s390x (zero based) + autopkgtest support. + + -- Tiago Stürmer Daitx Fri, 17 Jan 2020 17:37:33 +0000 + +openjdk-8 (8u242-b04-1) unstable; urgency=medium + + * Update to 8u242-b04 (early access build). + + -- Matthias Klose Mon, 06 Jan 2020 20:59:40 +0100 + +openjdk-8 (8u232-b09-1) unstable; urgency=high + + * Update to 8u222-b09 (release build). * Security fixes: - S8167646: Better invalid FilePermission. - S8213429, CVE-2019-2933: Windows file handling redux. @@ -32,17 +98,9 @@ - S8226765, CVE-2019-2999: Commentary on Javadoc comments. - S8227129: Better ligature for subtables. - S8227601: Better collection of references. - - S8228825, CVE-2019-2894: Enhance ECDSA operations . - - -- Tiago Stürmer Daitx Wed, 16 Oct 2019 00:44:38 +0000 - -openjdk-8 (8u232-b07-2ubuntu1) eoan; urgency=medium - - * Use the hotspot arch list to select between hotspot and zero as - the default VM for autopkgtests. This fixes s390x (zero based) - autopkgtest support. + - S8228825, CVE-2019-2894: Enhance ECDSA operations. - -- Tiago Stürmer Daitx Fri, 11 Oct 2019 13:27:59 +0000 + -- Matthias Klose Thu, 17 Oct 2019 22:41:19 +0200 openjdk-8 (8u232-b07-2) unstable; urgency=medium diff -Nru openjdk-8-8u232-b09/debian/rules openjdk-8-8u242-b08/debian/rules --- openjdk-8-8u232-b09/debian/rules 2019-10-16 20:38:15.000000000 +0000 +++ openjdk-8-8u242-b08/debian/rules 2020-01-17 23:41:21.000000000 +0000 @@ -1983,19 +1983,20 @@ is_release = is_release = yes hg_project = jdk8u -hg_tag = jdk8u232-ga +hg_tag = jdk8u242-b08 package_version = $(subst jdk,,$(hg_tag)) ifneq ($(is_release),yes) package_version := $(subst -,~,$(package_version)) endif hg_url = http://hg.openjdk.java.net/jdk8u/$(hg_project) hg_project_aarch64 = jdk8u-shenandoah -hg_tag_aarch64 = aarch64-shenandoah-jdk8u232-b09 +hg_tag_aarch64 = aarch64-shenandoah-jdk8u242-b07 hg_url_aarch64 = http://hg.openjdk.java.net/aarch64-port/$(hg_project_aarch64) hg_project_aarch32 = jdk8u -hg_tag_aarch32 = jdk8u232-b08-aarch32-191010 +hg_tag_aarch32 = jdk8u242-b07-aarch32-200115 hg_url_aarch32 = http://hg.openjdk.java.net/aarch32-port/$(hg_project_aarch32) origdir = ../openjdk-8-$(package_version).orig +orig_tarball = ../openjdk-8_$(package_version).orig.tar.xz source_date := $(shell dpkg-parsechangelog | sed -n '/^Date: /{s///p;q;}') fetch-orig: mkdir -p $(origdir) @@ -2049,7 +2050,8 @@ tar --clamp-mtime --mtime="$(source_date)" -cJf $(origdir)/$$repo.tar.xz $$repo; \ rm -rf $$repo; \ rm -f $(origdir)/$$repo.tar.bz2; \ - done + done; \ + tar --clamp-mtime --mtime="$(source_date)" -cJf $(orig_tarball) -C.. $$(basename $(origdir)); get-orig: fetch-orig dfsg-orig binary: binary-arch binary-indep Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/hotspot-aarch32.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/hotspot-aarch32.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/hotspot-aarch64.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/hotspot-aarch64.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/hotspot.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/hotspot.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/jaxp.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/jaxp.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/jaxws.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/jaxws.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/jdk.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/jdk.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/langtools.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/langtools.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/nashorn.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/nashorn.tar.xz differ Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/root.tar.xz and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/root.tar.xz differ diff -Nru openjdk-8-8u232-b09/=unpacked-tar1=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar1=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar1=/.hg_archival.txt 2019-09-26 06:17:37.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar1=/.hg_archival.txt 2020-01-13 04:57:40.000000000 +0000 @@ -1,5 +1,4 @@ repo: cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d -node: 6b9f309807a227d32bfcad2ab36cdbccd71d38ca +node: 5b17d1f49219624f122ea2b05ec1c9f1adff8c64 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar1=/.hgtags openjdk-8-8u242-b08/=unpacked-tar1=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar1=/.hgtags 2019-09-26 06:17:37.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar1=/.hgtags 2020-01-13 04:57:40.000000000 +0000 @@ -973,6 +973,16 @@ c5ca527b0afdafb0072f5e0810de13ec326e4b57 jdk8u232-b03 9611ccdff5fe10bb27e5aa34cde295562d13a29b jdk8u232-b04 2cd484c5b7f8463f5db0a73da92199255c212810 jdk8u232-b05 +a29e19e1c0ee5eeb9c46c9158b395b4c10735157 jdk8u242-b00 aa1559aa1f70d79e8bd4f3de9ab9a48fe1c0cc78 jdk8u232-b06 54af8189b95d47ea2cf8bdc9d90fb02d46a1fd38 jdk8u232-b07 7aea873d47e1d93c7ef4902e758417e5afc19d9c jdk8u232-b08 +6b9f309807a227d32bfcad2ab36cdbccd71d38ca jdk8u232-b09 +6b9f309807a227d32bfcad2ab36cdbccd71d38ca jdk8u232-ga +34aa7bcd731f29c1a37aad70a5f07272a3fa9ca7 jdk8u242-b01 +d2079934980013fdd8e63e31897011edae1a1188 jdk8u242-b02 +be3a6b2c79821f056a9ca1efde037555d829ccb8 jdk8u242-b03 +813d61736302c853dd0ef1b1e92b8fd0ca0af123 jdk8u242-b04 +bb4532c15611d35d3136eeb287049da79ce01ebb jdk8u242-b05 +72443ad60b1e685bd50e7ec8f21adf66786863d1 jdk8u242-b06 +8ca5f59e3042b7353b64c131be6bb970ba489ce9 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar1=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar1=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar1=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar1=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar10=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar10=/.hg_archival.txt 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/.hg_archival.txt 2020-01-13 04:58:09.000000000 +0000 @@ -1,5 +1,4 @@ repo: b8a1b238c77c7c00024daaa2cb7d10838e017b5f -node: fba077f48da23f914f13b11718464a547215b7f6 +node: 0704986602a8506f41e5a4648d724be74f1e6f95 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/.hgtags openjdk-8-8u242-b08/=unpacked-tar10=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar10=/.hgtags 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/.hgtags 2020-01-13 04:58:09.000000000 +0000 @@ -1045,6 +1045,16 @@ 7979e4a31f24adbcf19c9f8f23ac147be5dd4d12 jdk8u232-b03 41756665474f7bc4ffc591c23887678eb2490ea6 jdk8u232-b04 52afbdfa7852542f5aa3021336ed7b7069c42997 jdk8u232-b05 +8a951fd037e245425bbfe061a426a2250096b1ea jdk8u242-b00 d9dd9b7ce13f7b6ff0124c47106cadf5499e7554 jdk8u232-b06 0f61e27241b57c8ed5cd9b4d0324ac0d3b0daf13 jdk8u232-b07 9fc2e50a5c2f98fce148bbe35e43fc17395e3afc jdk8u232-b08 +fba077f48da23f914f13b11718464a547215b7f6 jdk8u232-b09 +fba077f48da23f914f13b11718464a547215b7f6 jdk8u232-ga +6c540cfd25937bfddc5825a243a40a6615a9dddd jdk8u242-b01 +49b31f2616534d74144a4fa8480609e70dc56c06 jdk8u242-b02 +2c0573615bbb89bd2b522d0b4619ef513d3f51dd jdk8u242-b03 +6375475624314776773afbd023fabae34054cf52 jdk8u242-b04 +735e7a309c5b0623bf25b29a0a1e7e437d56a43c jdk8u242-b05 +0735b1dcec3677634ca632683ca14911431a236a jdk8u242-b06 +1bccea33f6dbb43bf0cb74b82bd9669aba5319ab jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java --- openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java 2020-01-13 04:58:09.000000000 +0000 @@ -541,7 +541,6 @@ sprev = s; s++; } - sprev = sbegin; // break; } private void opAnyCharMLStar() { @@ -550,7 +549,6 @@ sprev = s; s++; } - sprev = sbegin; // break; } private void opAnyCharStarPeekNext() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java --- openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java 2020-01-13 04:58:09.000000000 +0000 @@ -45,6 +45,7 @@ final int NREGION = 10; final int MAX_BACKREF_NUM = 1000; + final int MAX_CAPTURE_GROUP_NUM = 0x8000; final int MAX_REPEAT_NUM = 100000; final int MAX_MULTI_BYTE_RANGES_NUM = 10000; diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java --- openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java 2020-01-13 04:58:09.000000000 +0000 @@ -31,6 +31,7 @@ final String ERR_PARSER_BUG = "internal parser error (bug)"; final String ERR_UNDEFINED_BYTECODE = "undefined bytecode (bug)"; final String ERR_UNEXPECTED_BYTECODE = "unexpected bytecode (bug)"; + final String ERR_TOO_MANY_CAPTURE_GROUPS = "too many capture groups"; /* syntax error */ final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace"; diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java --- openjdk-8-8u232-b09/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java 2019-05-24 14:53:44.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java 2020-01-13 04:58:09.000000000 +0000 @@ -62,6 +62,9 @@ } public int addMemEntry() { + if (numMem >= Config.MAX_CAPTURE_GROUP_NUM) { + throw new InternalException(ErrorMessages.ERR_TOO_MANY_CAPTURE_GROUPS); + } if (numMem++ == 0) { memNodes = new Node[SCANENV_MEMNODES_SIZE]; } else if (numMem >= memNodes.length) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/test/script/basic/JDK-8204288.js openjdk-8-8u242-b08/=unpacked-tar10=/test/script/basic/JDK-8204288.js --- openjdk-8-8u232-b09/=unpacked-tar10=/test/script/basic/JDK-8204288.js 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/test/script/basic/JDK-8204288.js 2020-01-13 04:58:09.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8204288: Matching the end of a string followed by an empty greedy regex and a word boundary fails + * + * @test + * @run + */ + + +Assert.assertEquals(new RegExp("c.*\\b").exec("abc")[0], "c"); +Assert.assertEquals(new RegExp("abc.*\\b").exec("abc")[0], "abc"); +Assert.assertEquals(new RegExp("\\b.*abc.*\\b").exec("abc")[0], "abc"); + diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/test/script/basic/JDK-8204290.js openjdk-8-8u242-b08/=unpacked-tar10=/test/script/basic/JDK-8204290.js --- openjdk-8-8u232-b09/=unpacked-tar10=/test/script/basic/JDK-8204290.js 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/test/script/basic/JDK-8204290.js 2020-01-13 04:58:09.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8204290: Add check to limit number of capture groups + * + * @test + * @run + */ + +try { + var captureGroups = ""; + for (i=0; i < 0x8001; i++) { captureGroups += "()"; } + new RegExp(captureGroups); + fail("Expected exception"); +} catch (e) { + Assert.assertTrue(e instanceof SyntaxError); + Assert.assertEquals(e.message, "too many capture groups"); +} + diff -Nru openjdk-8-8u232-b09/=unpacked-tar10=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar10=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar10=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar10=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/shenandoah/ShenandoahHeap.java openjdk-8-8u242-b08/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/shenandoah/ShenandoahHeap.java --- openjdk-8-8u232-b09/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/shenandoah/ShenandoahHeap.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/shenandoah/ShenandoahHeap.java 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -27,9 +27,12 @@ import sun.jvm.hotspot.gc_interface.CollectedHeapName; import sun.jvm.hotspot.debugger.Address; import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.VMObjectFactory; import sun.jvm.hotspot.types.Type; import sun.jvm.hotspot.types.TypeDataBase; import sun.jvm.hotspot.memory.MemRegion; +import sun.jvm.hotspot.memory.SpaceClosure; +import sun.jvm.hotspot.types.AddressField; import sun.jvm.hotspot.types.CIntegerField; import sun.jvm.hotspot.types.JLongField; import java.io.PrintStream; @@ -40,6 +43,8 @@ static private CIntegerField numRegions; static private JLongField used; static private CIntegerField committed; + static private AddressField regions; + static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -53,6 +58,7 @@ numRegions = type.getCIntegerField("_num_regions"); used = type.getJLongField("_used"); committed = type.getCIntegerField("_committed"); + regions = type.getAddressField("_regions"); } @Override @@ -84,4 +90,20 @@ public ShenandoahHeap(Address addr) { super(addr); } + + public void iterateHeapRegions(SpaceClosure scl) { + for (long index = 0; index < numOfRegions(); index ++) { + ShenandoahHeapRegion region = at(index); + scl.doSpace(region); + } + } + + private ShenandoahHeapRegion at(long index) { + Address arrayAddr = regions.getValue(addr); + // Offset of &_regions[index] + long offset = index * VM.getVM().getAddressSize(); + Address regionAddr = arrayAddr.getAddressAt(offset); + return (ShenandoahHeapRegion) VMObjectFactory.newObject(ShenandoahHeapRegion.class, + regionAddr); + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java openjdk-8-8u242-b08/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- openjdk-8-8u232-b09/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java 2020-01-13 05:52:26.000000000 +0000 @@ -440,9 +440,7 @@ g1h.heapRegionIterate(lrc); } else if (heap instanceof ShenandoahHeap) { ShenandoahHeap sh = (ShenandoahHeap) heap; - // Operation (currently) not supported with Shenandoah GC. Print - // a warning and leave the list of live regions empty. - System.err.println("Warning: Operation not supported with Shenandoah GC"); + sh.iterateHeapRegions(lrc); } else { if (Assert.ASSERTS_ENABLED) { Assert.that(false, "Expecting GenCollectedHeap, G1CollectedHeap, " + diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar11=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar11=/.hg_archival.txt 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/.hg_archival.txt 2020-01-13 05:52:26.000000000 +0000 @@ -1,4 +1,4 @@ repo: a61af66fc99eb5ec9d50c05b0c599757b1289ceb -node: 9e52f8d3b51100bae86a8d43199243b0ee7ba93b +node: c81fd2ed614aca227695edd61feffc8f2c4baf87 branch: default -tag: aarch64-shenandoah-jdk8u232-b09 +tag: aarch64-shenandoah-jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/.hgtags openjdk-8-8u242-b08/=unpacked-tar11=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar11=/.hgtags 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/.hgtags 2020-01-13 05:52:26.000000000 +0000 @@ -1406,6 +1406,7 @@ b13d7942036329f64c77a93cffc25e1b52523a3c jdk8u232-b05 a047aebf12df4c2350f0590f6206bd7a3c60e63f aarch64-shenandoah-jdk8u232-b05 4eeba56c89849b25b2ffd984e097d6ebd16d538f aarch64-shenandoah-jdk8u232-b05-shenandoah-merge-2019-09-09 +760b28d871785cd508239a5f635cfb45451f9202 jdk8u242-b00 fea2c7f50ce8e6aee1e946eaec7b834193747d82 jdk8u232-b06 e2d7de285d766fe5d73e0874f927fe6d4b0130fc aarch64-shenandoah-jdk8u232-b06 c751303497d539aa85c6373aa0fa85580d3f3044 jdk8u232-b07 @@ -1413,3 +1414,17 @@ 4170228e11e6313e948e6ddcae9af3eed06b1fbe jdk8u232-b08 da542efab0101dfd47542fbae7d9021a56942d23 aarch64-shenandoah-jdk8u232-b08 12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-b09 +9e52f8d3b51100bae86a8d43199243b0ee7ba93b aarch64-shenandoah-jdk8u232-b09 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-ga +ce42ae95d4d671f74246091f89bd101d5bcbfd91 jdk8u242-b01 +e4c7daab7059dd96f6332a887927cfd6df9aad68 aarch64-shenandoah-jdk8u242-b01 +775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02 +e97d1987c8d9c263bffe802fa255d05d13d83a87 aarch64-shenandoah-jdk8u242-b02 +ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03 +20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04 +7cb8932d8a4fe0942540fa170e5be4ae1362888f aarch64-shenandoah-jdk8u242-b04 +2c1e9fab6964647f4eeffe55fe5592da6399a3ce jdk8u242-b05 +db6c24b84cb618b65d7f5c2b05e09dff716d72a3 aarch64-shenandoah-jdk8u242-b05 +81ddc1072b923330f84c0ace3124226f63877582 jdk8u242-b06 +918b505f4c613d6da87c8d06f987442548ab44d2 aarch64-shenandoah-jdk8u242-b06 +8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/make/excludeSrc.make openjdk-8-8u242-b08/=unpacked-tar11=/make/excludeSrc.make --- openjdk-8-8u232-b09/=unpacked-tar11=/make/excludeSrc.make 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/make/excludeSrc.make 2020-01-13 05:52:26.000000000 +0000 @@ -119,11 +119,11 @@ psMemoryPool.cpp Src_Files_EXCLUDE += \ - shenandoahBarrierSet_x86.cpp \ - shenandoahBarrierSet_aarch64.cpp \ - shenandoahBarrierSet_ppc.cpp \ - shenandoahBarrierSet_sparc.cpp \ - shenandoahBarrierSet_zero.cpp + shenandoahBarrierSetAssembler_x86.cpp \ + shenandoahBarrierSetAssembler_aarch64.cpp \ + shenandoahBarrierSetAssembler_ppc.cpp \ + shenandoahBarrierSetAssembler_sparc.cpp \ + shenandoahBarrierSetAssembler_zero.cpp endif ifeq ($(INCLUDE_NMT), false) diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/make/linux/makefiles/vm.make openjdk-8-8u242-b08/=unpacked-tar11=/make/linux/makefiles/vm.make --- openjdk-8-8u232-b09/=unpacked-tar11=/make/linux/makefiles/vm.make 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/make/linux/makefiles/vm.make 2020-01-13 05:52:26.000000000 +0000 @@ -188,8 +188,8 @@ Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS) Src_Dirs := $(Src_Dirs/$(TYPE)) -COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\* -COMPILER1_SPECIFIC_FILES := c1_\* +COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\* shenandoahBarrierSetC2.cpp shenandoahSupport.cpp +COMPILER1_SPECIFIC_FILES := c1_\* shenandoahBarrierSetC1.cpp SHARK_SPECIFIC_FILES := shark ZERO_SPECIFIC_FILES := zero diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/aarch64.ad openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/aarch64.ad --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/aarch64.ad 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/aarch64.ad 2020-01-13 05:52:26.000000000 +0000 @@ -926,7 +926,9 @@ source_hpp %{ -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#endif class CallStubImpl { @@ -1184,10 +1186,22 @@ bool is_CAS(int opcode) { - return (opcode == Op_CompareAndSwapI || - opcode == Op_CompareAndSwapL || - opcode == Op_CompareAndSwapN || - opcode == Op_CompareAndSwapP); + switch(opcode) { + // We handle these + case Op_CompareAndSwapI: + case Op_CompareAndSwapL: + case Op_CompareAndSwapP: + case Op_CompareAndSwapN: + case Op_GetAndSetI: + case Op_GetAndSetL: + case Op_GetAndSetP: + case Op_GetAndSetN: + case Op_GetAndAddI: + case Op_GetAndAddL: + return true; + default: + return false; + } } // predicates controlling emit of ldr/ldar and associated dmb @@ -2764,7 +2778,7 @@ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} @@ -2791,7 +2805,7 @@ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} @@ -7793,21 +7807,6 @@ ins_pipe(ialu_reg); %} -instruct shenandoahRB(iRegPNoSp dst, iRegP src, rFlagsReg cr) %{ - match(Set dst (ShenandoahReadBarrier src)); - format %{ "shenandoah_rb $dst,$src" %} - ins_encode %{ -#if INCLUDE_ALL_GCS - Register s = $src$$Register; - Register d = $dst$$Register; - __ ldr(d, Address(s, ShenandoahBrooksPointer::byte_offset())); -#else - ShouldNotReachHere(); -#endif - %} - ins_pipe(pipe_class_memory); -%} - // Convert oop pointer into compressed form instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); @@ -8149,7 +8148,7 @@ ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); @@ -8265,7 +8264,7 @@ ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); @@ -8273,6 +8272,7 @@ instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ match(Set prev (GetAndSetI mem newv)); + ins_cost(2 * VOLATILE_REF_COST); format %{ "atomic_xchgw $prev, $newv, [$mem]" %} ins_encode %{ __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); @@ -8282,6 +8282,7 @@ instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ match(Set prev (GetAndSetL mem newv)); + ins_cost(2 * VOLATILE_REF_COST); format %{ "atomic_xchg $prev, $newv, [$mem]" %} ins_encode %{ __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); @@ -8291,6 +8292,7 @@ instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ match(Set prev (GetAndSetN mem newv)); + ins_cost(2 * VOLATILE_REF_COST); format %{ "atomic_xchgw $prev, $newv, [$mem]" %} ins_encode %{ __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); @@ -8300,6 +8302,7 @@ instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ match(Set prev (GetAndSetP mem newv)); + ins_cost(2 * VOLATILE_REF_COST); format %{ "atomic_xchg $prev, $newv, [$mem]" %} ins_encode %{ __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); @@ -8307,10 +8310,54 @@ ins_pipe(pipe_serial); %} +instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set prev (GetAndSetI mem newv)); + ins_cost(VOLATILE_REF_COST); + format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} + ins_encode %{ + __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set prev (GetAndSetL mem newv)); + ins_cost(VOLATILE_REF_COST); + format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} + ins_encode %{ + __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set prev (GetAndSetN mem newv)); + ins_cost(VOLATILE_REF_COST); + format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} + ins_encode %{ + __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set prev (GetAndSetP mem newv)); + ins_cost(VOLATILE_REF_COST); + format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} + ins_encode %{ + __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ match(Set newval (GetAndAddL mem incr)); - ins_cost(INSN_COST * 10); + ins_cost(2 * VOLATILE_REF_COST + 1); format %{ "get_and_addL $newval, [$mem], $incr" %} ins_encode %{ __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); @@ -8321,7 +8368,7 @@ instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ predicate(n->as_LoadStore()->result_not_used()); match(Set dummy (GetAndAddL mem incr)); - ins_cost(INSN_COST * 9); + ins_cost(2 * VOLATILE_REF_COST); format %{ "get_and_addL [$mem], $incr" %} ins_encode %{ __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); @@ -8331,7 +8378,7 @@ instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ match(Set newval (GetAndAddL mem incr)); - ins_cost(INSN_COST * 10); + ins_cost(2 * VOLATILE_REF_COST + 1); format %{ "get_and_addL $newval, [$mem], $incr" %} ins_encode %{ __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); @@ -8342,7 +8389,7 @@ instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ predicate(n->as_LoadStore()->result_not_used()); match(Set dummy (GetAndAddL mem incr)); - ins_cost(INSN_COST * 9); + ins_cost(2 * VOLATILE_REF_COST); format %{ "get_and_addL [$mem], $incr" %} ins_encode %{ __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); @@ -8352,7 +8399,7 @@ instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ match(Set newval (GetAndAddI mem incr)); - ins_cost(INSN_COST * 10); + ins_cost(2 * VOLATILE_REF_COST + 1); format %{ "get_and_addI $newval, [$mem], $incr" %} ins_encode %{ __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); @@ -8363,7 +8410,7 @@ instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ predicate(n->as_LoadStore()->result_not_used()); match(Set dummy (GetAndAddI mem incr)); - ins_cost(INSN_COST * 9); + ins_cost(2 * VOLATILE_REF_COST); format %{ "get_and_addI [$mem], $incr" %} ins_encode %{ __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); @@ -8373,7 +8420,7 @@ instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ match(Set newval (GetAndAddI mem incr)); - ins_cost(INSN_COST * 10); + ins_cost(2 * VOLATILE_REF_COST + 1); format %{ "get_and_addI $newval, [$mem], $incr" %} ins_encode %{ __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); @@ -8384,13 +8431,101 @@ instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ predicate(n->as_LoadStore()->result_not_used()); match(Set dummy (GetAndAddI mem incr)); - ins_cost(INSN_COST * 9); + ins_cost(2 * VOLATILE_REF_COST); format %{ "get_and_addI [$mem], $incr" %} ins_encode %{ __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); %} ins_pipe(pipe_serial); %} + +instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set newval (GetAndAddL mem incr)); + ins_cost(VOLATILE_REF_COST + 1); + format %{ "get_and_addL_acq $newval, [$mem], $incr" %} + ins_encode %{ + __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ + predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); + match(Set dummy (GetAndAddL mem incr)); + ins_cost(VOLATILE_REF_COST); + format %{ "get_and_addL_acq [$mem], $incr" %} + ins_encode %{ + __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set newval (GetAndAddL mem incr)); + ins_cost(VOLATILE_REF_COST + 1); + format %{ "get_and_addL_acq $newval, [$mem], $incr" %} + ins_encode %{ + __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ + predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); + match(Set dummy (GetAndAddL mem incr)); + ins_cost(VOLATILE_REF_COST); + format %{ "get_and_addL_acq [$mem], $incr" %} + ins_encode %{ + __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set newval (GetAndAddI mem incr)); + ins_cost(VOLATILE_REF_COST + 1); + format %{ "get_and_addI_acq $newval, [$mem], $incr" %} + ins_encode %{ + __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ + predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); + match(Set dummy (GetAndAddI mem incr)); + ins_cost(VOLATILE_REF_COST); + format %{ "get_and_addI_acq [$mem], $incr" %} + ins_encode %{ + __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set newval (GetAndAddI mem incr)); + ins_cost(VOLATILE_REF_COST + 1); + format %{ "get_and_addI_acq $newval, [$mem], $incr" %} + ins_encode %{ + __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} + +instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ + predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); + match(Set dummy (GetAndAddI mem incr)); + ins_cost(VOLATILE_REF_COST); + format %{ "get_and_addI_acq [$mem], $incr" %} + ins_encode %{ + __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); + %} + ins_pipe(pipe_serial); +%} // ============================================================================ // Conditional Move Instructions diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -42,7 +42,9 @@ #include "runtime/sharedRuntime.hpp" #include "vmreg_aarch64.inline.hpp" - +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#endif #ifndef PRODUCT #define COMMENT(x) do { __ block_comment(x); } while (0) @@ -1158,33 +1160,6 @@ -#if INCLUDE_ALL_GCS -void LIR_Assembler::emit_opShenandoahWriteBarrier(LIR_OpShenandoahWriteBarrier* op) { - - Register obj = op->in_opr()->as_register(); - Register res = op->result_opr()->as_register(); - - Label done; - - __ block_comment("Shenandoah write barrier {"); - - if (res != obj) { - __ mov(res, obj); - } - // Check for null. - if (op->need_null_check()) { - __ cbz(res, done); - } - - __ shenandoah_write_barrier(res); - - __ bind(done); - - __ block_comment("} Shenandoah write barrier"); - -} -#endif - void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { LIR_Opr src = op->in_opr(); LIR_Opr dest = op->result_opr(); @@ -1662,7 +1637,7 @@ Register t2 = op->tmp2()->as_register(); __ encode_heap_oop(t2, newval); newval = t2; - __ cmpxchg_oop_shenandoah(addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); } else #endif { @@ -1676,7 +1651,7 @@ } else { #if INCLUDE_ALL_GCS if (UseShenandoahGC && ShenandoahCASBarrier) { - __ cmpxchg_oop_shenandoah(addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); } else #endif { @@ -1979,7 +1954,7 @@ // cpu register - cpu register Register reg2 = opr2->as_register(); if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { - __ cmpoops(reg1, reg2); + __ cmp(reg1, reg2); } else { assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?"); __ cmpw(reg1, reg2); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -39,6 +39,10 @@ #include "runtime/stubRoutines.hpp" #include "vmreg_aarch64.inline.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#endif + #ifdef ASSERT #define __ gen()->lir(__FILE__, __LINE__)-> #else @@ -354,27 +358,16 @@ null_check_info = new CodeEmitInfo(range_check_info); } - LIR_Opr ary = array.result(); - LIR_Opr val = value.result(); - value = NULL; - -#if INCLUDE_ALL_GCS - ary = shenandoah_write_barrier(ary, null_check_info, x->needs_null_check()); - if (obj_store && UseShenandoahGC) { - val = shenandoah_read_barrier(val, NULL, true); - } -#endif - // emit array address setup early so it schedules better // FIXME? No harm in this on aarch64, and it might help - LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), obj_store); + LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store); if (GenerateRangeChecks && needs_range_check) { if (use_length) { __ cmp(lir_cond_belowEqual, length.result(), index.result()); __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); } else { - array_range_check(ary, index.result(), null_check_info, range_check_info); + array_range_check(array.result(), index.result(), null_check_info, range_check_info); // range_check also does the null check null_check_info = NULL; } @@ -386,18 +379,18 @@ LIR_Opr tmp3 = new_register(objectType); CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info); - __ store_check(val, ary, tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); + __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); } if (obj_store) { // Needs GC write barriers. pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); - __ move(val, array_addr, null_check_info); + __ move(value.result(), array_addr, null_check_info); // Seems to be a precise - post_barrier(LIR_OprFact::address(array_addr), val); + post_barrier(LIR_OprFact::address(array_addr), value.result()); } else { - LIR_Opr result = maybe_mask_boolean(x, ary, val, null_check_info); + LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); __ move(result, array_addr, null_check_info); } } @@ -424,11 +417,7 @@ // this CodeEmitInfo must not have the xhandlers because here the // object is already locked (xhandlers expect object to be unlocked) CodeEmitInfo* info = state_for(x, x->state(), true); - LIR_Opr obj_opr = obj.result(); -#if INCLUDE_ALL_GCS - obj_opr = shenandoah_write_barrier(obj_opr, state_for(x), x->needs_null_check()); -#endif - monitor_enter(obj_opr, lock, syncTempOpr(), scratch, + monitor_enter(obj.result(), lock, syncTempOpr(), scratch, x->monitor_no(), info_for_exception, info); } @@ -813,27 +802,21 @@ cmp.load_item(); LIR_Address* a; - - LIR_Opr obj_op = obj.result(); -#if INCLUDE_ALL_GCS - obj_op = shenandoah_write_barrier(obj_op, NULL, true); -#endif - if(offset.result()->is_constant()) { jlong c = offset.result()->as_jlong(); if ((jlong)((jint)c) == c) { - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), (jint)c, as_BasicType(type)); } else { LIR_Opr tmp = new_register(T_LONG); __ move(offset.result(), tmp); - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), tmp, as_BasicType(type)); } } else { - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), offset.result(), LIR_Address::times_1, 0, @@ -849,27 +832,23 @@ } LIR_Opr result = rlock_result(x); - LIR_Opr val_op = val.result(); LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience if (type == objectType) { -#if INCLUDE_ALL_GCS - val_op = shenandoah_read_barrier(val_op, NULL, true); -#endif - __ cas_obj(addr, cmp.result(), val_op, new_register(T_INT), new_register(T_INT), + __ cas_obj(addr, cmp.result(), val.result(), new_register(T_INT), new_register(T_INT), result); } else if (type == intType) - __ cas_int(addr, cmp.result(), val_op, ill, ill, result); + __ cas_int(addr, cmp.result(), val.result(), ill, ill, result); else if (type == longType) - __ cas_long(addr, cmp.result(), val_op, ill, ill, result); + __ cas_long(addr, cmp.result(), val.result(), ill, ill, result); else { ShouldNotReachHere(); } if (type == objectType) { // Write-barrier needed for Object fields. // Seems to be precise - post_barrier(addr, val_op); + post_barrier(addr, val.result()); } } @@ -953,13 +932,6 @@ LIRItem dst_pos(x->argument_at(3), this); LIRItem length(x->argument_at(4), this); - LIR_Opr dst_op = dst.result(); - LIR_Opr src_op = src.result(); -#if INCLUDE_ALL_GCS - dst_op = shenandoah_write_barrier(dst_op, info, x->arg_needs_null_check(2)); - src_op = shenandoah_read_barrier(src_op, info, x->arg_needs_null_check(0)); -#endif - // operands for arraycopy must use fixed registers, otherwise // LinearScan will fail allocation (because arraycopy always needs a // call) @@ -972,9 +944,9 @@ // of the C convention we can process the java args trivially into C // args without worry of overwriting during the xfer - src_op = force_opr_to(src_op, FrameMap::as_oop_opr(j_rarg0)); + src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); - dst_op = force_opr_to(dst_op, FrameMap::as_oop_opr(j_rarg2)); + dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); length.load_item_force (FrameMap::as_opr(j_rarg4)); @@ -986,7 +958,7 @@ ciArrayKlass* expected_type; arraycopy_helper(x, &flags, &expected_type); - __ arraycopy(src_op, src_pos.result(), dst_op, dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint + __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint } void LIRGenerator::do_update_CRC32(Intrinsic* x) { @@ -1030,12 +1002,6 @@ index = tmp; } -#if INCLUDE_ALL_GCS - if (is_updateBytes) { - base_op = shenandoah_read_barrier(base_op, NULL, false); - } -#endif - if (offset) { LIR_Opr tmp = new_pointer_register(); __ add(base_op, LIR_OprFact::intConst(offset), tmp); @@ -1401,9 +1367,6 @@ void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, BasicType type, bool is_volatile) { -#if INCLUDE_ALL_GCS - src = shenandoah_read_barrier(src, NULL, true); -#endif LIR_Address* addr = new LIR_Address(src, offset, type); __ load(addr, dst); } @@ -1411,19 +1374,12 @@ void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, BasicType type, bool is_volatile) { -#if INCLUDE_ALL_GCS - src = shenandoah_write_barrier(src, NULL, true); -#endif - LIR_Address* addr = new LIR_Address(src, offset, type); bool is_obj = (type == T_ARRAY || type == T_OBJECT); if (is_obj) { // Do the pre-write barrier, if any. pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); -#if INCLUDE_ALL_GCS - data = shenandoah_read_barrier(data, NULL, true); -#endif __ move(data, addr); assert(src->is_register(), "must be register"); // Seems to be a precise address @@ -1462,21 +1418,14 @@ LIR_Opr src_op = src.result(); -#if INCLUDE_ALL_GCS - src_op = shenandoah_write_barrier(src_op, NULL, true); - if (is_obj) { - data = shenandoah_read_barrier(data, NULL, true); - } -#endif - LIR_Address* addr; if (offset->is_constant()) { jlong l = offset->as_jlong(); assert((jlong)((jint)l) == l, "offset too large for constant"); jint c = (jint)l; - addr = new LIR_Address(src_op, c, type); + addr = new LIR_Address(src.result(), c, type); } else { - addr = new LIR_Address(src_op, offset, type); + addr = new LIR_Address(src.result(), offset, type); } LIR_Opr tmp = new_register(T_INT); @@ -1493,6 +1442,14 @@ true /* do_load */, false /* patch */, NULL); } __ xchg(LIR_OprFact::address(addr), data, dst, tmp); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && is_obj) { + dst = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, dst, NULL, true); + LIR_Opr tmp = new_register(type); + __ move(dst, tmp); + dst = tmp; + } +#endif if (is_obj) { post_barrier(ptr, data); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -877,6 +877,7 @@ __ sub(arr_size, arr_size, t1); // body length __ add(t1, t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); + __ membar(Assembler::StoreStore); __ verify_oop(obj); __ ret(lr); @@ -905,6 +906,7 @@ __ sub(arr_size, arr_size, t1); // body length __ add(t1, t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); + __ membar(Assembler::StoreStore); __ verify_oop(obj); __ ret(lr); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/interp_masm_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/interp_masm_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/interp_masm_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/interp_masm_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -273,7 +273,6 @@ ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); // JNIHandles::resolve(obj); ldr(result, Address(result, 0)); - oopDesc::bs()->interpreter_read_barrier_not_null(this, result); // Add in the index add(result, result, tmp); load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -88,7 +88,6 @@ __ andr(robj, robj, ~JNIHandles::weak_tag_mask); __ ldr(robj, Address(robj, 0)); // *obj - oopDesc::bs()->interpreter_read_barrier(masm, robj); __ lsr(roffset, c_rarg2, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,10 +34,6 @@ #include "compiler/disassembler.hpp" #include "gc_interface/collectedHeap.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "memory/resourceArea.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/interfaceSupport.hpp" @@ -58,6 +54,7 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" +#include "shenandoahBarrierSetAssembler_aarch64.hpp" #endif #ifdef COMPILER2 @@ -2212,64 +2209,6 @@ } } -void MacroAssembler::cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, - bool acquire, bool release, bool weak, bool is_cae, - Register result) { - - Register tmp1 = rscratch1; - Register tmp2 = rscratch2; - bool is_narrow = UseCompressedOops; - Assembler::operand_size size = is_narrow ? Assembler::word : Assembler::xword; - - assert_different_registers(addr, expected, new_val, tmp1, tmp2); - - Label retry, done, fail; - - // CAS, using LL/SC pair. - bind(retry); - load_exclusive(tmp1, addr, size, acquire); - if (is_narrow) { - cmpw(tmp1, expected); - } else { - cmp(tmp1, expected); - } - br(Assembler::NE, fail); - store_exclusive(tmp2, new_val, addr, size, release); - if (weak) { - cmpw(tmp2, 0u); // If the store fails, return NE to our caller - } else { - cbnzw(tmp2, retry); - } - b(done); - - bind(fail); - // Check if rb(expected)==rb(tmp1) - // Shuffle registers so that we have memory value ready for next expected. - mov(tmp2, expected); - mov(expected, tmp1); - if (is_narrow) { - decode_heap_oop(tmp1, tmp1); - decode_heap_oop(tmp2, tmp2); - } - oopDesc::bs()->interpreter_read_barrier(this, tmp1); - oopDesc::bs()->interpreter_read_barrier(this, tmp2); - cmp(tmp1, tmp2); - // Retry with expected now being the value we just loaded from addr. - br(Assembler::EQ, retry); - if (is_cae && is_narrow) { - // For cmp-and-exchange and narrow oops, we need to restore - // the compressed old-value. We moved it to 'expected' a few lines up. - mov(result, expected); - } - bind(done); - - if (is_cae) { - mov(result, tmp1); - } else { - cset(result, Assembler::EQ); - } -} - static bool different(Register a, RegisterOrConstant b, Register c) { if (b.is_constant()) return a != c; @@ -3186,11 +3125,6 @@ store_check_part_2(obj); } -void MacroAssembler::cmpoops(Register src1, Register src2) { - cmp(src1, src2); - oopDesc::bs()->asm_acmp_barrier(this, src1, src2); -} - void MacroAssembler::store_check(Register obj, Address dst) { store_check(obj); } @@ -3218,6 +3152,10 @@ // don't bother to check, but it could save an instruction. intptr_t disp = (intptr_t) ct->byte_map_base; load_byte_map_base(rscratch1); + + if (UseConcMarkSweepGC && CMSPrecleaningEnabled) { + membar(StoreStore); + } strb(zr, Address(obj, rscratch1)); } @@ -3537,6 +3475,12 @@ } else { ldr(dst, src); } + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + ShenandoahBarrierSetAssembler::bsasm()->load_reference_barrier(this, dst); + } +#endif } void MacroAssembler::load_heap_oop_not_null(Register dst, Address src) @@ -3547,6 +3491,12 @@ } else { ldr(dst, src); } + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + ShenandoahBarrierSetAssembler::bsasm()->load_reference_barrier(this, dst); + } +#endif } void MacroAssembler::store_heap_oop(Address dst, Register src) { @@ -3758,47 +3708,6 @@ bind(done); } -void MacroAssembler::shenandoah_write_barrier(Register dst) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "Should be enabled"); - assert(dst != rscratch1, "need rscratch1"); - assert(dst != rscratch2, "need rscratch2"); - - Label done; - - Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset())); - ldrb(rscratch1, gc_state); - - // Check for heap stability - mov(rscratch2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - tst(rscratch1, rscratch2); - br(Assembler::EQ, done); - - // Heap is unstable, need to perform the read-barrier even if WB is inactive - ldr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset())); - - // Check for evacuation-in-progress and jump to WB slow-path if needed - mov(rscratch2, ShenandoahHeap::EVACUATION); - tst(rscratch1, rscratch2); - br(Assembler::EQ, done); - - RegSet to_save = RegSet::of(r0); - if (dst != r0) { - push(to_save, sp); - mov(r0, dst); - } - - assert(StubRoutines::aarch64::shenandoah_wb() != NULL, "need write barrier stub"); - far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::aarch64::shenandoah_wb()))); - - if (dst != r0) { - mov(dst, r0); - pop(to_save, sp); - } - block_comment("} Shenandoah write barrier"); - - bind(done); -} - #endif // INCLUDE_ALL_GCS Address MacroAssembler::allocate_metadata_address(Metadata* obj) { @@ -3860,15 +3769,10 @@ // verify_tlab(); - int oop_extra_words = Universe::heap()->oop_extra_words(); - ldr(obj, Address(rthread, JavaThread::tlab_top_offset())); if (var_size_in_bytes == noreg) { - lea(end, Address(obj, con_size_in_bytes + oop_extra_words * HeapWordSize)); + lea(end, Address(obj, con_size_in_bytes)); } else { - if (oop_extra_words > 0) { - add(var_size_in_bytes, var_size_in_bytes, oop_extra_words * HeapWordSize); - } lea(end, Address(obj, var_size_in_bytes)); } ldr(rscratch1, Address(rthread, JavaThread::tlab_end_offset())); @@ -3878,8 +3782,6 @@ // update the tlab top pointer str(end, Address(rthread, JavaThread::tlab_top_offset())); - Universe::heap()->compile_prepare_oop(this, obj); - // recover var_size_in_bytes if necessary if (var_size_in_bytes == end) { sub(var_size_in_bytes, var_size_in_bytes, obj); @@ -4901,7 +4803,7 @@ mov(result, false); // same array? - cmpoops(ary1, ary2); + cmp(ary1, ary2); br(Assembler::EQ, SAME); // ne if either null diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -777,8 +777,6 @@ Register tmp, Register tmp2); - void shenandoah_write_barrier(Register dst); - #endif // INCLUDE_ALL_GCS // split store_check(Register obj) to enhance instruction interleaving @@ -971,8 +969,6 @@ void addptr(const Address &dst, int32_t src); void cmpptr(Register src1, Address src2); - void cmpoops(Register src1, Register src2); - void cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp, Label &suceed, Label *fail); @@ -1004,8 +1000,6 @@ bool acquire, bool release, Register tmp = rscratch1); - void cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, - bool acquire, bool release, bool weak, bool is_cae, Register result); // Calls address trampoline_call(Address entry, CodeBuffer *cbuf = NULL); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/methodHandles_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/methodHandles_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/methodHandles_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/methodHandles_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -132,13 +132,10 @@ //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); }); // Load the invoker, as MH -> MH.form -> LF.vmentry - oopDesc::bs()->interpreter_read_barrier(_masm, recv); __ verify_oop(recv); __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()))); - oopDesc::bs()->interpreter_read_barrier(_masm, method_temp); __ verify_oop(method_temp); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()))); - oopDesc::bs()->interpreter_read_barrier(_masm, method_temp); __ verify_oop(method_temp); // the following assumes that a Method* is normally compressed in the vmtarget field: __ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()))); @@ -152,7 +149,7 @@ // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); Label L; __ ldr(rscratch1, __ argument_address(temp2, -1)); - __ cmpoops(recv, rscratch1); + __ cmp(recv, rscratch1); __ br(Assembler::EQ, L); __ ldr(r0, __ argument_address(temp2, -1)); __ hlt(0); @@ -330,7 +327,6 @@ // r13 - interpreter linkage (if interpreted) ??? FIXME // r1 ... r0 - compiler arguments (if compiled) - oopDesc::bs()->interpreter_read_barrier(_masm, member_reg); Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1719,8 +1719,6 @@ // Load the oop from the handle __ ldr(obj_reg, Address(oop_handle_reg, 0)); - oopDesc::bs()->interpreter_write_barrier(masm, obj_reg); - if (UseBiasedLocking) { __ biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, lock_done, &slow_path_lock); } @@ -1888,7 +1886,6 @@ // Get locked oop from the handle we passed to jni __ ldr(obj_reg, Address(oop_handle_reg, 0)); - oopDesc::bs()->interpreter_write_barrier(masm, obj_reg); Label done; @@ -1947,7 +1944,7 @@ __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value)); __ verify_oop(r0); #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { __ g1_write_barrier_pre(noreg /* obj */, r0 /* pre_val */, rthread /* thread */, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSet_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSet_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSet_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSet_aarch64.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" - -#include "asm/macroAssembler.hpp" -#include "interpreter/interpreter.hpp" - -#define __ masm-> - -#ifndef CC_INTERP -void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { - if (ShenandoahReadBarrier) { - Label is_null; - __ cbz(dst, is_null); - interpreter_read_barrier_not_null(masm, dst); - __ bind(is_null); - } -} - -void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - if (ShenandoahReadBarrier) { - __ ldr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset())); - } -} - -void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { - if (! ShenandoahWriteBarrier) { - return interpreter_read_barrier(masm, dst); - } - - assert(dst != rscratch1, "different regs"); - assert(dst != rscratch2, "Need rscratch2"); - - Label done; - - Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset())); - __ ldrb(rscratch1, gc_state); - - // Check for heap stability - __ mov(rscratch2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - __ tst(rscratch1, rscratch2); - __ br(Assembler::EQ, done); - - // Heap is unstable, need to perform the read-barrier even if WB is inactive - __ ldr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset())); - - // Check for evacuation-in-progress and jump to WB slow-path if needed - __ mov(rscratch2, ShenandoahHeap::EVACUATION); - __ tst(rscratch1, rscratch2); - __ br(Assembler::EQ, done); - - __ lsr(rscratch1, dst, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr()); - __ ldrb(rscratch2, Address(rscratch2, rscratch1)); - __ tst(rscratch2, 0x1); - __ br(Assembler::EQ, done); - - // Save possibly live regs. - RegSet live_regs = RegSet::range(r0, r4) - dst; - __ push(live_regs, sp); - __ strd(v0, __ pre(sp, 2 * -wordSize)); - - // Call into runtime - __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_IRT), dst); - - // Move result into dst reg. - __ mov(dst, r0); - - // Restore possibly live regs. - __ ldrd(v0, __ post(sp, 2 * wordSize)); - __ pop(live_regs, sp); - - __ bind(done); -} - -void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { - __ add(obj, obj, ShenandoahBrooksPointer::byte_size()); - __ str(obj, Address(obj, -1 * HeapWordSize)); -} - -void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, - Register op1, Register op2) { - assert(UseShenandoahGC, "Should be enabled"); - if (ShenandoahAcmpBarrier) { - Label done; - __ br(Assembler::EQ, done); - // The object may have been evacuated, but we won't see it without a - // membar here. - __ membar(Assembler::LoadStore|Assembler::LoadLoad); - interpreter_read_barrier(masm, op1); - interpreter_read_barrier(masm, op2); - __ cmp(op1, op2); - __ bind(done); - } -} - -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_MacroAssembler.hpp" +#include "c1/c1_LIRAssembler.hpp" +#include "macroAssembler_aarch64.hpp" +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahRuntime.hpp" +#include "runtime/stubCodeGenerator.hpp" +#include "runtime/thread.hpp" + +ShenandoahBarrierSetAssembler* ShenandoahBarrierSetAssembler::bsasm() { + return ShenandoahBarrierSet::barrier_set()->bsasm(); +} + +#define __ masm-> + +void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) { + assert(ShenandoahCASBarrier, "should be enabled"); + Label is_null; + __ cbz(dst, is_null); + resolve_forward_pointer_not_null(masm, dst, tmp); + __ bind(is_null); +} + +// IMPORTANT: This must preserve all registers, even rscratch1 and rscratch2, except those explicitely +// passed in. +void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) { + assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled"); + // The below loads the mark word, checks if the lowest two bits are + // set, and if so, clear the lowest two bits and copy the result + // to dst. Otherwise it leaves dst alone. + // Implementing this is surprisingly awkward. I do it here by: + // - Inverting the mark word + // - Test lowest two bits == 0 + // - If so, set the lowest two bits + // - Invert the result back, and copy to dst + + bool borrow_reg = (tmp == noreg); + if (borrow_reg) { + // No free registers available. Make one useful. + tmp = rscratch1; + if (tmp == dst) { + tmp = rscratch2; + } + __ push(RegSet::of(tmp), sp); + } + + assert_different_registers(tmp, dst); + + Label done; + __ ldr(tmp, Address(dst, oopDesc::mark_offset_in_bytes())); + __ eon(tmp, tmp, zr); + __ ands(zr, tmp, markOopDesc::lock_mask_in_place); + __ br(Assembler::NE, done); + __ orr(tmp, tmp, markOopDesc::marked_value); + __ eon(dst, tmp, zr); + __ bind(done); + + if (borrow_reg) { + __ pop(RegSet::of(tmp), sp); + } +} + +void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) { + assert(ShenandoahLoadRefBarrier, "Should be enabled"); + assert(dst != rscratch2, "need rscratch2"); + + Label done; + __ enter(); + Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset())); + __ ldrb(rscratch2, gc_state); + + // Check for heap stability + __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); + + RegSet to_save = RegSet::of(r0); + if (dst != r0) { + __ push(to_save, sp); + __ mov(r0, dst); + } + + __ push_call_clobbered_registers(); + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_interpreter), r0); + __ mov(rscratch1, r0); + __ pop_call_clobbered_registers(); + __ mov(r0, rscratch1); + + if (dst != r0) { + __ mov(dst, r0); + __ pop(to_save, sp); + } + + __ bind(done); + __ leave(); +} + +void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { + if (ShenandoahStoreValEnqueueBarrier) { + // Save possibly live regs. + RegSet live_regs = RegSet::range(r0, r4) - dst; + __ push(live_regs, sp); + __ strd(v0, __ pre(sp, 2 * -wordSize)); + + __ g1_write_barrier_pre(noreg, dst, rthread, tmp, true, false); + + // Restore possibly live regs. + __ ldrd(v0, __ post(sp, 2 * wordSize)); + __ pop(live_regs, sp); + } +} + +void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) { + if (ShenandoahLoadRefBarrier) { + Label is_null; + __ cbz(dst, is_null); + load_reference_barrier_not_null(masm, dst); + __ bind(is_null); + } +} + +void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val, + bool acquire, bool release, bool weak, bool is_cae, + Register result) { + + Register tmp1 = rscratch1; + Register tmp2 = rscratch2; + bool is_narrow = UseCompressedOops; + Assembler::operand_size size = is_narrow ? Assembler::word : Assembler::xword; + + assert_different_registers(addr, expected, new_val, tmp1, tmp2); + + Label retry, done, fail; + + // CAS, using LL/SC pair. + __ bind(retry); + __ load_exclusive(tmp1, addr, size, acquire); + if (is_narrow) { + __ cmpw(tmp1, expected); + } else { + __ cmp(tmp1, expected); + } + __ br(Assembler::NE, fail); + __ store_exclusive(tmp2, new_val, addr, size, release); + if (weak) { + __ cmpw(tmp2, 0u); // If the store fails, return NE to our caller + } else { + __ cbnzw(tmp2, retry); + } + __ b(done); + + __ bind(fail); + // Check if rb(expected)==rb(tmp1) + // Shuffle registers so that we have memory value ready for next expected. + __ mov(tmp2, expected); + __ mov(expected, tmp1); + if (is_narrow) { + __ decode_heap_oop(tmp1, tmp1); + __ decode_heap_oop(tmp2, tmp2); + } + resolve_forward_pointer(masm, tmp1); + resolve_forward_pointer(masm, tmp2); + __ cmp(tmp1, tmp2); + // Retry with expected now being the value we just loaded from addr. + __ br(Assembler::EQ, retry); + if (is_cae && is_narrow) { + // For cmp-and-exchange and narrow oops, we need to restore + // the compressed old-value. We moved it to 'expected' a few lines up. + __ mov(result, expected); + } + __ bind(done); + + if (is_cae) { + __ mov(result, tmp1); + } else { + __ cset(result, Assembler::EQ); + } +} + +#undef __ + +#ifdef COMPILER1 + +#define __ ce->masm()-> + +void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub) { + + Register obj = stub->obj()->as_register(); + Register res = stub->result()->as_register(); + + Label done; + + __ bind(*stub->entry()); + + if (res != obj) { + __ mov(res, obj); + } + // Check for null. + if (stub->needs_null_check()) { + __ cbz(res, done); + } + + load_reference_barrier_not_null(ce->masm(), res); + + __ bind(done); + __ b(*stub->continuation()); +} + +#undef __ + +#endif // COMPILER1 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_AARCH64_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_AARCH64_HPP +#define CPU_AARCH64_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_AARCH64_HPP + +#include "asm/macroAssembler.hpp" +#include "memory/allocation.hpp" +#ifdef COMPILER1 +class LIR_Assembler; +class ShenandoahLoadReferenceBarrierStub; +class StubAssembler; +class StubCodeGenerator; +#endif + +class ShenandoahBarrierSetAssembler : public CHeapObj { +private: + + void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg); + void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg); + + void load_reference_barrier_not_null(MacroAssembler* masm, Register dst); + +public: + static ShenandoahBarrierSetAssembler* bsasm(); + + void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp); + +#ifdef COMPILER1 + void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub); +#endif + + void load_reference_barrier(MacroAssembler* masm, Register dst); + + virtual void cmpxchg_oop(MacroAssembler* masm, + Register addr, Register expected, Register new_val, + bool acquire, bool release, bool weak, bool is_cae, + Register result); +}; + +#endif // CPU_AARCH64_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_AARCH64_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,10 +27,6 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_aarch64.hpp" #include "oops/instanceOop.hpp" @@ -522,58 +518,6 @@ return start; } - // Shenandoah write barrier. - // - // Input: - // r0: OOP to evacuate. Not null. - // - // Output: - // r0: Pointer to evacuated OOP. - // - // Trash rscratch1, rscratch2. Preserve everything else. - - address generate_shenandoah_wb(bool c_abi, bool do_cset_test) { - StubCodeMark mark(this, "StubRoutines", "shenandoah_wb"); - - __ align(6); - address start = __ pc(); - - if (do_cset_test) { - Label work; - __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr()); - __ lsr(rscratch1, r0, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - __ ldrb(rscratch2, Address(rscratch2, rscratch1)); - __ tbnz(rscratch2, 0, work); - __ ret(lr); - __ bind(work); - } - - Register obj = r0; - - __ enter(); // required for proper stackwalking of RuntimeStub frame - - if (!c_abi) { - __ push_call_clobbered_registers(); - } else { - __ push_call_clobbered_fp_registers(); - } - - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_JRT)); - __ blr(lr); - if (!c_abi) { - __ mov(rscratch1, obj); - __ pop_call_clobbered_registers(); - __ mov(obj, rscratch1); - } else { - __ pop_call_clobbered_fp_registers(); - } - - __ leave(); // required for proper stackwalking of RuntimeStub frame - __ ret(lr); - - return start; - } - // Non-destructive plausibility checks for oops // // Arguments: @@ -739,6 +683,9 @@ const Register count = end; // 'end' register contains bytes count now __ load_byte_map_base(scratch); __ add(start, start, scratch); + if (UseConcMarkSweepGC) { + __ membar(__ StoreStore); + } __ BIND(L_loop); __ strb(zr, Address(start, count)); __ subs(count, count, 1); @@ -4296,11 +4243,6 @@ StubRoutines::_montgomerySquare = g.generate_multiply(); } - if (UseShenandoahGC && ShenandoahWriteBarrier) { - StubRoutines::aarch64::_shenandoah_wb = generate_shenandoah_wb(false, true); - StubRoutines::_shenandoah_wb_C = generate_shenandoah_wb(true, false); - } - if (UseAESIntrinsics) { StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -33,8 +33,6 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::aarch64::_shenandoah_wb = NULL; - address StubRoutines::aarch64::_get_previous_fp_entry = NULL; address StubRoutines::aarch64::_get_previous_sp_entry = NULL; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,15 +37,13 @@ enum platform_dependent_constants { code_size1 = 19000, // simply increase if too small (assembler will crash if too small) - code_size2 = 28000 // simply increase if too small (assembler will crash if too small) + code_size2 = 22000 // simply increase if too small (assembler will crash if too small) }; class aarch64 { friend class StubGenerator; private: - static address _shenandoah_wb; - static address _get_previous_fp_entry; static address _get_previous_sp_entry; @@ -63,11 +61,6 @@ public: - static address shenandoah_wb() - { - return _shenandoah_wb; - } - static address get_previous_fp_entry() { return _get_previous_fp_entry; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -573,7 +573,6 @@ #endif // ASSERT __ bind(done); - oopDesc::bs()->interpreter_write_barrier(_masm, r0); } // add space for monitor & lock @@ -694,7 +693,7 @@ const int referent_offset = java_lang_ref_Reference::referent_offset; guarantee(referent_offset > 0, "referent offset not initialized"); - if (UseG1GC || UseShenandoahGC) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { Label slow_path; const Register local_0 = c_rarg0; // Check if local 0 != NULL @@ -703,8 +702,6 @@ __ mov(r19, r13); // First call-saved register __ cbz(local_0, slow_path); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, local_0); - // Load the value of the referent field. const Address field_address(local_0, referent_offset); __ load_heap_oop(local_0, field_address); @@ -831,7 +828,6 @@ __ ldrw(crc, Address(esp, 4*wordSize)); // Initial CRC } else { __ ldr(buf, Address(esp, 2*wordSize)); // byte[] array - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, buf); __ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size __ ldrw(off, Address(esp, wordSize)); // offset __ add(buf, buf, off); // + offset @@ -1191,7 +1187,7 @@ // Resolve jweak. __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value)); #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { __ enter(); // Barrier may call runtime. __ g1_write_barrier_pre(noreg /* obj */, r0 /* pre_val */, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/templateTable_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/templateTable_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/templateTable_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/templateTable_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -38,6 +38,9 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#endif #ifndef CC_INTERP @@ -152,7 +155,6 @@ #if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: - case BarrierSet::ShenandoahBarrierSet: { // flatten object address if needed if (obj.index() == noreg && obj.offset() == 0) { @@ -177,8 +179,6 @@ new_val = rscratch2; __ mov(new_val, val); } - // For Shenandoah, make sure we only store refs into to-space. - oopDesc::bs()->interpreter_read_barrier(_masm, val); __ store_heap_oop(Address(r3, 0), val); @@ -191,6 +191,35 @@ } break; + case BarrierSet::ShenandoahBarrierSet: + { + // flatten object address if needed + if (obj.index() == noreg && obj.offset() == 0) { + if (obj.base() != r3) { + __ mov(r3, obj.base()); + } + } else { + __ lea(r3, obj); + } + if (ShenandoahSATBBarrier) { + __ g1_write_barrier_pre(r3 /* obj */, + r1 /* pre_val */, + rthread /* thread */, + r10 /* tmp */, + val != noreg /* tosca_live */, + false /* expand_call */); + } + if (val == noreg) { + __ store_heap_oop_null(Address(r3, 0)); + } else { + if (ShenandoahStoreValEnqueueBarrier) { + ShenandoahBarrierSetAssembler::bsasm()->storeval_barrier(_masm, val, r10); + } + __ store_heap_oop(Address(r3, 0), val); + } + + } + break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: @@ -681,7 +710,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(2))); __ ldrw(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_INT))); } @@ -694,7 +722,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(3))); __ ldr(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_LONG))); } @@ -707,7 +734,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(2))); __ ldrs(v0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_FLOAT))); } @@ -720,7 +746,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(3))); __ ldrd(v0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_DOUBLE))); } @@ -733,7 +758,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); int s = (UseCompressedOops ? 2 : 3); __ lea(r1, Address(r0, r1, Address::uxtw(s))); __ load_heap_oop(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); @@ -747,7 +771,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(0))); __ load_signed_byte(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_BYTE))); } @@ -760,7 +783,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(1))); __ load_unsigned_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_CHAR))); } @@ -778,7 +800,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(1))); __ load_unsigned_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_CHAR))); } @@ -791,7 +812,6 @@ // r0: array // r1: index index_check(r0, r1); // leaves index in r1, kills rscratch1 - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); __ lea(r1, Address(r0, r1, Address::uxtw(1))); __ load_signed_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_SHORT))); } @@ -981,7 +1001,6 @@ // r1: index // r3: array index_check(r3, r1); // prefer index in r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(rscratch1, Address(r3, r1, Address::uxtw(2))); __ strw(r0, Address(rscratch1, arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -995,7 +1014,6 @@ // r1: index // r3: array index_check(r3, r1); // prefer index in r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(rscratch1, Address(r3, r1, Address::uxtw(3))); __ str(r0, Address(rscratch1, arrayOopDesc::base_offset_in_bytes(T_LONG))); @@ -1009,7 +1027,6 @@ // r1: index // r3: array index_check(r3, r1); // prefer index in r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(rscratch1, Address(r3, r1, Address::uxtw(2))); __ strs(v0, Address(rscratch1, arrayOopDesc::base_offset_in_bytes(T_FLOAT))); @@ -1023,7 +1040,6 @@ // r1: index // r3: array index_check(r3, r1); // prefer index in r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(rscratch1, Address(r3, r1, Address::uxtw(3))); __ strd(v0, Address(rscratch1, arrayOopDesc::base_offset_in_bytes(T_DOUBLE))); @@ -1040,7 +1056,6 @@ Address element_address(r4, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); index_check(r3, r2); // kills r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(r4, Address(r3, r2, Address::uxtw(UseCompressedOops? 2 : 3))); // do array store check - check for NULL value first @@ -1091,7 +1106,6 @@ // r0: value // r1: index // r3: array - oopDesc::bs()->interpreter_write_barrier(_masm, r3); index_check(r3, r1); // prefer index in r1 // Need to check whether array is boolean or byte @@ -1119,7 +1133,6 @@ // r1: index // r3: array index_check(r3, r1); // prefer index in r1 - oopDesc::bs()->interpreter_write_barrier(_masm, r3); __ lea(rscratch1, Address(r3, r1, Address::uxtw(1))); __ strh(r0, Address(rscratch1, arrayOopDesc::base_offset_in_bytes(T_CHAR))); @@ -1964,7 +1977,7 @@ // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(r1); - __ cmpoops(r1, r0); + __ cmp(r1, r0); __ br(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -2428,7 +2441,6 @@ // obj is on the stack pop_and_check_object(obj); } - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, obj); // 8179954: We need to make sure that the code generated for // volatile accesses forms a sequentially-consistent set of @@ -2687,7 +2699,6 @@ { __ pop(btos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strb(r0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_bputfield, bc, r1, true, byte_no); @@ -2703,7 +2714,6 @@ { __ pop(ztos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ andw(r0, r0, 0x1); __ strb(r0, field); if (!is_static) { @@ -2720,7 +2730,6 @@ { __ pop(atos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); // Store into the field do_oop_store(_masm, field, r0, _bs->kind(), false); if (!is_static) { @@ -2737,7 +2746,6 @@ { __ pop(itos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strw(r0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_iputfield, bc, r1, true, byte_no); @@ -2753,7 +2761,6 @@ { __ pop(ctos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strh(r0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_cputfield, bc, r1, true, byte_no); @@ -2769,7 +2776,6 @@ { __ pop(stos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strh(r0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_sputfield, bc, r1, true, byte_no); @@ -2785,7 +2791,6 @@ { __ pop(ltos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ str(r0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, bc, r1, true, byte_no); @@ -2801,7 +2806,6 @@ { __ pop(ftos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strs(v0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_fputfield, bc, r1, true, byte_no); @@ -2819,7 +2823,6 @@ { __ pop(dtos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ strd(v0, field); if (!is_static) { patch_bytecode(Bytecodes::_fast_dputfield, bc, r1, true, byte_no); @@ -2937,7 +2940,6 @@ // Get object from stack pop_and_check_object(r2); - oopDesc::bs()->interpreter_write_barrier(_masm, r2); // field address const Address field(r2, r1); @@ -3019,7 +3021,6 @@ // r0: object __ verify_oop(r0); __ null_check(r0); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); const Address field(r0, r1); // 8179954: We need to make sure that the code generated for @@ -3103,7 +3104,6 @@ // next instruction) __ increment(rbcp); __ null_check(r0); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, r0); switch (state) { case itos: __ ldrw(r0, Address(r0, r1, Address::lsl(0))); @@ -3779,11 +3779,6 @@ // check for NULL object __ null_check(r0); - // We need to preemptively evacuate the object, because we later compare - // it to objects in the BasicObjectLock list, and we might get false negatives - // if another thread evacuates the object in the meantime. See acmp. - oopDesc::bs()->interpreter_write_barrier(_masm, r0); - const Address monitor_block_top( rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( @@ -3883,11 +3878,6 @@ // check for NULL object __ null_check(r0); - // We need to preemptively evacuate the object, because we later compare - // it to objects in the BasicObjectLock list, and we might get false negatives - // if another thread evacuates the object in the meantime. See acmp. - oopDesc::bs()->interpreter_write_barrier(_masm, r0); - const Address monitor_block_top( rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/vm_version_aarch64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/vm_version_aarch64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/aarch64/vm/vm_version_aarch64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/aarch64/vm/vm_version_aarch64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,7 +1,6 @@ /* * Copyright (c) 2013, Red Hat Inc. - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. - * All rights reserved. + * Copyright (c) 1997, 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 @@ -227,6 +226,11 @@ } } + if (UseGHASHIntrinsics) { + warning("GHASH intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { UseCRC32Intrinsics = true; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/ppc/vm/shenandoahBarrierSet_ppc.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/ppc/vm/shenandoahBarrierSet_ppc.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/ppc/vm/shenandoahBarrierSet_ppc.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/ppc/vm/shenandoahBarrierSet_ppc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" - -#include "asm/macroAssembler.hpp" -#include "interpreter/interpreter.hpp" - -#define __ masm-> - -#ifndef CC_INTERP - -void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { - Unimplemented(); -} - -void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { - Unimplemented(); -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/ppc/vm/vm_version_ppc.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/ppc/vm/vm_version_ppc.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/ppc/vm/vm_version_ppc.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/ppc/vm/vm_version_ppc.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -194,6 +194,11 @@ FLAG_SET_DEFAULT(UseAESIntrinsics, false); } + if (UseGHASHIntrinsics) { + warning("GHASH intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + if (has_vshasig()) { if (FLAG_IS_DEFAULT(UseSHA)) { UseSHA = true; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/assembler_sparc.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/assembler_sparc.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/assembler_sparc.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/assembler_sparc.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -129,6 +129,7 @@ flog3_op3 = 0x36, edge_op3 = 0x36, fsrc_op3 = 0x36, + xmulx_op3 = 0x36, impdep2_op3 = 0x37, stpartialf_op3 = 0x37, jmpl_op3 = 0x38, @@ -220,6 +221,8 @@ mdtox_opf = 0x110, mstouw_opf = 0x111, mstosw_opf = 0x113, + xmulx_opf = 0x115, + xmulxhi_opf = 0x116, mxtod_opf = 0x118, mwtos_opf = 0x119, @@ -1212,6 +1215,9 @@ void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + void xmulx(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulx_opf) | rs2(s2)); } + void xmulxhi(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulxhi_opf) | rs2(s2)); } + // Crypto SHA instructions void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/shenandoahBarrierSet_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/shenandoahBarrierSet_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/shenandoahBarrierSet_sparc.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/shenandoahBarrierSet_sparc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" - -#include "asm/macroAssembler.hpp" -#include "interpreter/interpreter.hpp" - -#define __ masm-> - -#ifndef CC_INTERP - -void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { - Unimplemented(); -} - -void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { - Unimplemented(); -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/stubGenerator_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -4788,6 +4788,130 @@ return start; } + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_aligned, L_main; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + Register state = I0; + Register subkeyH = I1; + Register data = I2; + Register len = I3; + + __ save_frame(0); + + __ ldx(state, 0, O0); + __ ldx(state, 8, O1); + + // Loop label for multiblock operations + __ BIND(L_ghash_loop); + + // Check if 'data' is unaligned + __ andcc(data, 7, G1); + __ br(Assembler::zero, false, Assembler::pt, L_aligned); + __ delayed()->nop(); + + Register left_shift = L1; + Register right_shift = L2; + Register data_ptr = L3; + + // Get left and right shift values in bits + __ sll(G1, LogBitsPerByte, left_shift); + __ mov(64, right_shift); + __ sub(right_shift, left_shift, right_shift); + + // Align to read 'data' + __ sub(data, G1, data_ptr); + + // Load first 8 bytes of 'data' + __ ldx(data_ptr, 0, O4); + __ sllx(O4, left_shift, O4); + __ ldx(data_ptr, 8, O5); + __ srlx(O5, right_shift, G4); + __ bset(G4, O4); + + // Load second 8 bytes of 'data' + __ sllx(O5, left_shift, O5); + __ ldx(data_ptr, 16, G4); + __ srlx(G4, right_shift, G4); + __ ba(L_main); + __ delayed()->bset(G4, O5); + + // If 'data' is aligned, load normally + __ BIND(L_aligned); + __ ldx(data, 0, O4); + __ ldx(data, 8, O5); + + __ BIND(L_main); + __ ldx(subkeyH, 0, O2); + __ ldx(subkeyH, 8, O3); + + __ xor3(O0, O4, O0); + __ xor3(O1, O5, O1); + + __ xmulxhi(O0, O3, G3); + __ xmulx(O0, O2, O5); + __ xmulxhi(O1, O2, G4); + __ xmulxhi(O1, O3, G5); + __ xmulx(O0, O3, G1); + __ xmulx(O1, O3, G2); + __ xmulx(O1, O2, O3); + __ xmulxhi(O0, O2, O4); + + __ mov(0xE1, O0); + __ sllx(O0, 56, O0); + + __ xor3(O5, G3, O5); + __ xor3(O5, G4, O5); + __ xor3(G5, G1, G1); + __ xor3(G1, O3, G1); + __ srlx(G2, 63, O1); + __ srlx(G1, 63, G3); + __ sllx(G2, 63, O3); + __ sllx(G2, 58, O2); + __ xor3(O3, O2, O2); + + __ sllx(G1, 1, G1); + __ or3(G1, O1, G1); + + __ xor3(G1, O2, G1); + + __ sllx(G2, 1, G2); + + __ xmulxhi(G1, O0, O1); + __ xmulx(G1, O0, O2); + __ xmulxhi(G2, O0, O3); + __ xmulx(G2, O0, G1); + + __ xor3(O4, O1, O4); + __ xor3(O5, O2, O5); + __ xor3(O5, O3, O5); + + __ sllx(O4, 1, O2); + __ srlx(O5, 63, O3); + + __ or3(O2, O3, O0); + + __ sllx(O5, 1, O1); + __ srlx(G1, 63, O2); + __ or3(O1, O2, O1); + __ xor3(O1, G3, O1); + + __ deccc(len); + __ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop); + __ delayed()->add(data, 16, data); + + __ stx(O0, I0, 0); + __ stx(O1, I0, 8); + + __ ret(); + __ delayed()->restore(); + + return start; + } + void generate_initial() { // Generates all stubs and initializes the entry points @@ -4860,6 +4984,10 @@ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } // generate SHA1/SHA256/SHA512 intrinsics code if (UseSHA1Intrinsics) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/vm_version_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/vm_version_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/sparc/vm/vm_version_sparc.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/sparc/vm/vm_version_sparc.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -286,39 +286,50 @@ // SPARC T4 and above should have support for AES instructions if (has_aes()) { - if (UseVIS > 2) { // AES intrinsics use MOVxTOd/MOVdTOx which are VIS3 - if (FLAG_IS_DEFAULT(UseAES)) { - FLAG_SET_DEFAULT(UseAES, true); - } - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - FLAG_SET_DEFAULT(UseAESIntrinsics, true); - } - // we disable both the AES flags if either of them is disabled on the command line - if (!UseAES || !UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAES, false); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + if (FLAG_IS_DEFAULT(UseAES)) { + FLAG_SET_DEFAULT(UseAES, true); + } + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); } else { - if (UseAES || UseAESIntrinsics) { - warning("SPARC AES intrinsics require VIS3 instruction support. Intrinsics will be disabled."); - if (UseAES) { - FLAG_SET_DEFAULT(UseAES, false); - } - if (UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAESIntrinsics, false); - } + // The AES intrinsic stubs require AES instruction support (of course) + // but also require VIS3 mode or higher for instructions it use. + if (UseVIS > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("SPARC AES intrinsics require VIS3 instructions. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } } else if (UseAES || UseAESIntrinsics) { - warning("AES instructions are not available on this CPU"); - if (UseAES) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { + warning("AES instructions are not available on this CPU"); FLAG_SET_DEFAULT(UseAES, false); } - if (UseAESIntrinsics) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); FLAG_SET_DEFAULT(UseAESIntrinsics, false); } } + // GHASH/GCM intrinsics + if (has_vis3() && (UseVIS > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; + } + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times if (has_sha1() || has_sha256() || has_sha512()) { if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -2575,6 +2575,15 @@ emit_int8(shift); } +void Assembler::pslldq(XMMRegister dst, int shift) { + // Shift left 128 bit value in xmm register by number of bytes. + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66); + emit_int8(0x73); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(shift); +} + void Assembler::ptest(XMMRegister dst, Address src) { assert(VM_Version::supports_sse4_1(), ""); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/assembler_x86.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1527,6 +1527,8 @@ // Shift Right by bytes Logical DoubleQuadword Immediate void psrldq(XMMRegister dst, int shift); + // Shift Left by bytes Logical DoubleQuadword Immediate + void pslldq(XMMRegister dst, int shift); // Logical Compare 128bit void ptest(XMMRegister dst, XMMRegister src); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -40,6 +40,9 @@ #include "runtime/sharedRuntime.hpp" #include "vmreg_x86.inline.hpp" +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif // These masks are used to provide 128-bit aligned bitmasks to the XMM // instructions, to allow sign-masking or sign-bit flipping. They allow @@ -1513,29 +1516,6 @@ } } -#if INCLUDE_ALL_GCS -void LIR_Assembler::emit_opShenandoahWriteBarrier(LIR_OpShenandoahWriteBarrier* op) { - Label done; - Register obj = op->in_opr()->as_register(); - Register res = op->result_opr()->as_register(); - - if (res != obj) { - __ mov(res, obj); - } - - // Check for null. - if (op->need_null_check()) { - __ testptr(res, res); - __ jcc(Assembler::zero, done); - } - - __ shenandoah_write_barrier(res); - - __ bind(done); - -} -#endif - void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { LIR_Opr src = op->in_opr(); LIR_Opr dest = op->result_opr(); @@ -2029,7 +2009,7 @@ __ encode_heap_oop(cmpval); __ mov(rscratch1, newval); __ encode_heap_oop(rscratch1); - __ cmpxchg_oop_shenandoah(NULL, Address(addr, 0), cmpval, rscratch1, true, tmp1, tmp2); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, NULL, Address(addr, 0), cmpval, rscratch1, true, tmp1, tmp2); } else #endif { @@ -2049,7 +2029,7 @@ if (UseShenandoahGC && ShenandoahCASBarrier) { Register tmp1 = op->tmp1()->as_register(); Register tmp2 = op->tmp2()->as_register(); - __ cmpxchg_oop_shenandoah(NULL, Address(addr, 0), cmpval, newval, true, tmp1, tmp2); + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, NULL, Address(addr, 0), cmpval, newval, true, tmp1, tmp2); } else #endif { @@ -2746,7 +2726,7 @@ if (opr2->is_single_cpu()) { // cpu register - cpu register if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { - __ cmpoops(reg1, opr2->as_register()); + __ cmpptr(reg1, opr2->as_register()); } else { assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?"); __ cmpl(reg1, opr2->as_register()); @@ -2754,7 +2734,7 @@ } else if (opr2->is_stack()) { // cpu register - stack if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { - __ cmpoops(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); } else { __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); } @@ -2771,7 +2751,7 @@ } else { #ifdef _LP64 __ movoop(rscratch1, o); - __ cmpoops(reg1, rscratch1); + __ cmpptr(reg1, rscratch1); #else __ cmpoop(reg1, c->as_jobject()); #endif // _LP64 @@ -2884,7 +2864,7 @@ #ifdef _LP64 // %%% Make this explode if addr isn't reachable until we figure out a // better strategy by giving noreg as the temp for as_Address - __ cmpoops(rscratch1, as_Address(addr, noreg)); + __ cmpptr(rscratch1, as_Address(addr, noreg)); #else __ cmpoop(as_Address(addr), c->as_jobject()); #endif // _LP64 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -43,6 +43,10 @@ #define __ gen()->lir()-> #endif +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#endif + // Item will be loaded into a byte register; Intel only void LIRItem::load_byte_item() { load_item(); @@ -300,25 +304,15 @@ null_check_info = new CodeEmitInfo(range_check_info); } - LIR_Opr ary = array.result(); - LIR_Opr val = value.result(); - -#if INCLUDE_ALL_GCS - ary = shenandoah_write_barrier(ary, null_check_info, x->needs_null_check()); - if (obj_store && UseShenandoahGC) { - val = shenandoah_read_barrier(val, NULL, true); - } -#endif - // emit array address setup early so it schedules better - LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), obj_store); + LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store); if (GenerateRangeChecks && needs_range_check) { if (use_length) { __ cmp(lir_cond_belowEqual, length.result(), index.result()); __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); } else { - array_range_check(ary, index.result(), null_check_info, range_check_info); + array_range_check(array.result(), index.result(), null_check_info, range_check_info); // range_check also does the null check null_check_info = NULL; } @@ -330,18 +324,18 @@ LIR_Opr tmp3 = new_register(objectType); CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info); - __ store_check(val, ary, tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); + __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); } if (obj_store) { // Needs GC write barriers. pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); - __ move(val, array_addr, null_check_info); + __ move(value.result(), array_addr, null_check_info); // Seems to be a precise post_barrier(LIR_OprFact::address(array_addr), value.result()); } else { - LIR_Opr result = maybe_mask_boolean(x, ary, val, null_check_info); + LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); __ move(result, array_addr, null_check_info); } } @@ -369,11 +363,7 @@ // this CodeEmitInfo must not have the xhandlers because here the // object is already locked (xhandlers expect object to be unlocked) CodeEmitInfo* info = state_for(x, x->state(), true); - LIR_Opr obj_opr = obj.result(); -#if INCLUDE_ALL_GCS - obj_opr = shenandoah_write_barrier(obj_opr, state_for(x), x->needs_null_check()); -#endif - monitor_enter(obj_opr, lock, syncTempOpr(), scratch, + monitor_enter(obj.result(), lock, syncTempOpr(), scratch, x->monitor_no(), info_for_exception, info); } @@ -765,33 +755,27 @@ LIR_Opr addr = new_pointer_register(); LIR_Address* a; - - LIR_Opr obj_op = obj.result(); -#if INCLUDE_ALL_GCS - obj_op = shenandoah_write_barrier(obj_op, NULL, true); -#endif - if(offset.result()->is_constant()) { #ifdef _LP64 jlong c = offset.result()->as_jlong(); if ((jlong)((jint)c) == c) { - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), (jint)c, as_BasicType(type)); } else { LIR_Opr tmp = new_register(T_LONG); __ move(offset.result(), tmp); - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), tmp, as_BasicType(type)); } #else - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), offset.result()->as_jint(), as_BasicType(type)); #endif } else { - a = new LIR_Address(obj_op, + a = new LIR_Address(obj.result(), offset.result(), LIR_Address::times_1, 0, @@ -806,19 +790,20 @@ } LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience - - LIR_Opr val_op = val.result(); - if (type == objectType) { #if INCLUDE_ALL_GCS - val_op = shenandoah_read_barrier(val_op, NULL, true); + if (UseShenandoahGC) { + __ cas_obj(addr, cmp.result(), val.result(), new_register(T_OBJECT), new_register(T_OBJECT)); + } else #endif - __ cas_obj(addr, cmp.result(), val_op, new_register(T_OBJECT), new_register(T_OBJECT)); + { + __ cas_obj(addr, cmp.result(), val.result(), ill, ill); + } } else if (type == intType) - __ cas_int(addr, cmp.result(), val_op, ill, ill); + __ cas_int(addr, cmp.result(), val.result(), ill, ill); else if (type == longType) - __ cas_long(addr, cmp.result(), val_op, ill, ill); + __ cas_long(addr, cmp.result(), val.result(), ill, ill); else { ShouldNotReachHere(); } @@ -829,7 +814,7 @@ result, as_BasicType(type)); if (type == objectType) { // Write-barrier needed for Object fields. // Seems to be precise - post_barrier(addr, val_op); + post_barrier(addr, val.result()); } } @@ -921,25 +906,14 @@ LIRItem dst_pos(x->argument_at(3), this); LIRItem length(x->argument_at(4), this); - dst.load_item(); - LIR_Opr dst_op = dst.result(); -#if INCLUDE_ALL_GCS - dst_op = shenandoah_write_barrier(dst_op, info, x->arg_needs_null_check(2)); -#endif - src.load_item(); - LIR_Opr src_op = src.result(); -#if INCLUDE_ALL_GCS - src_op = shenandoah_read_barrier(src_op, info, x->arg_needs_null_check(0)); -#endif - // operands for arraycopy must use fixed registers, otherwise // LinearScan will fail allocation (because arraycopy always needs a // call) #ifndef _LP64 - src_op = force_opr_to(src_op, FrameMap::rcx_oop_opr); + src.load_item_force (FrameMap::rcx_oop_opr); src_pos.load_item_force (FrameMap::rdx_opr); - dst_op = force_opr_to(dst_op, FrameMap::rax_oop_opr); + dst.load_item_force (FrameMap::rax_oop_opr); dst_pos.load_item_force (FrameMap::rbx_opr); length.load_item_force (FrameMap::rdi_opr); LIR_Opr tmp = (FrameMap::rsi_opr); @@ -953,9 +927,9 @@ // of the C convention we can process the java args trivially into C // args without worry of overwriting during the xfer - src_op = force_opr_to(src_op, FrameMap::as_oop_opr(j_rarg0)); + src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); - dst_op = force_opr_to(dst_op, FrameMap::as_oop_opr(j_rarg2)); + dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); length.load_item_force (FrameMap::as_opr(j_rarg4)); @@ -968,7 +942,7 @@ ciArrayKlass* expected_type; arraycopy_helper(x, &flags, &expected_type); - __ arraycopy(src_op, src_pos.result(), dst_op, dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint + __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint } void LIRGenerator::do_update_CRC32(Intrinsic* x) { @@ -1019,12 +993,6 @@ } #endif -#if INCLUDE_ALL_GCS - if (is_updateBytes) { - base_op = shenandoah_read_barrier(base_op, NULL, false); - } -#endif - LIR_Address* a = new LIR_Address(base_op, index, LIR_Address::times_1, @@ -1441,9 +1409,6 @@ void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, BasicType type, bool is_volatile) { -#if INCLUDE_ALL_GCS - src = shenandoah_read_barrier(src, NULL, true); -#endif if (is_volatile && type == T_LONG) { LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); LIR_Opr tmp = new_register(T_DOUBLE); @@ -1461,9 +1426,6 @@ void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, BasicType type, bool is_volatile) { -#if INCLUDE_ALL_GCS - src = shenandoah_write_barrier(src, NULL, true); -#endif if (is_volatile && type == T_LONG) { LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); LIR_Opr tmp = new_register(T_DOUBLE); @@ -1479,9 +1441,6 @@ // Do the pre-write barrier, if any. pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); -#if INCLUDE_ALL_GCS - data = shenandoah_read_barrier(data, NULL, true); -#endif __ move(data, addr); assert(src->is_register(), "must be register"); // Seems to be a precise address @@ -1508,32 +1467,22 @@ LIR_Opr offset = off.result(); assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type"); - - LIR_Opr src_op = src.result(); - -#if INCLUDE_ALL_GCS - src_op = shenandoah_write_barrier(src_op, NULL, true); - if (is_obj) { - data = shenandoah_read_barrier(data, NULL, true); - } -#endif - LIR_Address* addr; if (offset->is_constant()) { #ifdef _LP64 jlong c = offset->as_jlong(); if ((jlong)((jint)c) == c) { - addr = new LIR_Address(src_op, (jint)c, type); + addr = new LIR_Address(src.result(), (jint)c, type); } else { LIR_Opr tmp = new_register(T_LONG); __ move(offset, tmp); - addr = new LIR_Address(src_op, tmp, type); + addr = new LIR_Address(src.result(), tmp, type); } #else - addr = new LIR_Address(src_op, offset->as_jint(), type); + addr = new LIR_Address(src.result(), offset->as_jint(), type); #endif } else { - addr = new LIR_Address(src_op, offset, type); + addr = new LIR_Address(src.result(), offset, type); } // Because we want a 2-arg form of xchg and xadd @@ -1548,6 +1497,16 @@ true /* do_load */, false /* patch */, NULL); } __ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr); + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && is_obj) { + dst = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, dst, NULL, true); + LIR_Opr tmp = new_register(type); + __ move(dst, tmp); + dst = tmp; + } +#endif + if (is_obj) { // Seems to be a precise address post_barrier(LIR_OprFact::address(addr), data); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/interp_masm_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/interp_masm_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/interp_masm_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/interp_masm_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -300,7 +300,6 @@ movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); // JNIHandles::resolve(obj); movptr(result, Address(result, 0)); - oopDesc::bs()->interpreter_read_barrier_not_null(this, result); // Add in the index addptr(result, tmp); load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/jniFastGetField_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/jniFastGetField_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/jniFastGetField_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/jniFastGetField_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -84,7 +84,6 @@ __ clear_jweak_tag(robj); __ movptr(robj, Address(robj, 0)); // *obj - oopDesc::bs()->interpreter_read_barrier(masm, robj); __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset @@ -186,7 +185,6 @@ __ clear_jweak_tag(robj); __ movptr(robj, Address(robj, 0)); // *obj - oopDesc::bs()->interpreter_read_barrier(masm, robj); __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -43,8 +43,8 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" +#include "shenandoahBarrierSetAssembler_x86.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #endif // INCLUDE_ALL_GCS #ifdef PRODUCT @@ -3856,103 +3856,6 @@ movl(as_Address(ArrayAddress(page, index)), tmp); } -// Special Shenandoah CAS implementation that handles false negatives -// due to concurrent evacuation. -#if INCLUDE_ALL_GCS -#ifndef _LP64 -void MacroAssembler::cmpxchg_oop_shenandoah(Register res, Address addr, Register oldval, Register newval, - bool exchange, - Register tmp1, Register tmp2) { - // Shenandoah has no 32-bit version for this. - Unimplemented(); -} -#else -void MacroAssembler::cmpxchg_oop_shenandoah(Register res, Address addr, Register oldval, Register newval, - bool exchange, - Register tmp1, Register tmp2) { - assert (UseShenandoahGC && ShenandoahCASBarrier, "Should only be used with Shenandoah"); - assert(oldval == rax, "must be in rax for implicit use in cmpxchg"); - - Label retry, done; - - // Remember oldval for retry logic below - if (UseCompressedOops) { - movl(tmp1, oldval); - } else { - movptr(tmp1, oldval); - } - - // Step 1. Try to CAS with given arguments. If successful, then we are done, - // and can safely return. - if (os::is_MP()) lock(); - if (UseCompressedOops) { - cmpxchgl(newval, addr); - } else { - cmpxchgptr(newval, addr); - } - jcc(Assembler::equal, done, true); - - // Step 2. CAS had failed. This may be a false negative. - // - // The trouble comes when we compare the to-space pointer with the from-space - // pointer to the same object. To resolve this, it will suffice to read both - // oldval and the value from memory through the read barriers -- this will give - // both to-space pointers. If they mismatch, then it was a legitimate failure. - // - if (UseCompressedOops) { - decode_heap_oop(tmp1); - } - oopDesc::bs()->interpreter_read_barrier(this, tmp1); - - if (UseCompressedOops) { - movl(tmp2, oldval); - decode_heap_oop(tmp2); - } else { - movptr(tmp2, oldval); - } - oopDesc::bs()->interpreter_read_barrier(this, tmp2); - - cmpptr(tmp1, tmp2); - jcc(Assembler::notEqual, done, true); - - // Step 3. Try to CAS again with resolved to-space pointers. - // - // Corner case: it may happen that somebody stored the from-space pointer - // to memory while we were preparing for retry. Therefore, we can fail again - // on retry, and so need to do this in loop, always re-reading the failure - // witness through the read barrier. - bind(retry); - if (os::is_MP()) lock(); - if (UseCompressedOops) { - cmpxchgl(newval, addr); - } else { - cmpxchgptr(newval, addr); - } - jcc(Assembler::equal, done, true); - - if (UseCompressedOops) { - movl(tmp2, oldval); - decode_heap_oop(tmp2); - } else { - movptr(tmp2, oldval); - } - oopDesc::bs()->interpreter_read_barrier(this, tmp2); - - cmpptr(tmp1, tmp2); - jcc(Assembler::equal, retry, true); - - // Step 4. If we need a boolean result out of CAS, check the flag again, - // and promote the result. Note that we handle the flag from both the CAS - // itself and from the retry loop. - bind(done); - if (!exchange) { - setb(Assembler::equal, res); - movzbl(res, res); - } -} -#endif // INCLUDE_ALL_GCS -#endif // LP64 - // Calls to C land // // When entering C land, the rbp, & rsp of the last Java frame have to be recorded @@ -4292,7 +4195,7 @@ if (UseShenandoahGC) { Address gc_state(thread, in_bytes(JavaThread::gc_state_offset())); - testb(gc_state, ShenandoahHeap::MARKING); + testb(gc_state, ShenandoahHeap::MARKING | ShenandoahHeap::TRAVERSAL); jcc(Assembler::zero, done); } else { assert(UseG1GC, "Should be"); @@ -4474,44 +4377,6 @@ bind(done); } -#ifndef _LP64 -void MacroAssembler::shenandoah_write_barrier(Register dst) { - Unimplemented(); -} -#else -void MacroAssembler::shenandoah_write_barrier(Register dst) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "Should be enabled"); - - Label done; - - Address gc_state(r15_thread, in_bytes(JavaThread::gc_state_offset())); - - // Check for heap stability - testb(gc_state, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - jccb(Assembler::zero, done); - - // Heap is unstable, need to perform the read-barrier even if WB is inactive - movptr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset())); - - // Check for evacuation-in-progress and jump to WB slow-path if needed - testb(gc_state, ShenandoahHeap::EVACUATION); - jccb(Assembler::zero, done); - - if (dst != rax) { - xchgptr(dst, rax); // Move obj into rax and save rax into obj. - } - - assert(StubRoutines::x86::shenandoah_wb() != NULL, "need write barrier stub"); - call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::shenandoah_wb()))); - - if (dst != rax) { - xchgptr(rax, dst); // Swap back obj with rax. - } - - bind(done); -} -#endif // _LP64 - #endif // INCLUDE_ALL_GCS ////////////////////////////////////////////////////////////////////////////////// @@ -4608,15 +4473,10 @@ NOT_LP64(get_thread(thread)); - uint oop_extra_words = Universe::heap()->oop_extra_words(); - movptr(obj, Address(thread, JavaThread::tlab_top_offset())); if (var_size_in_bytes == noreg) { - lea(end, Address(obj, con_size_in_bytes + oop_extra_words * HeapWordSize)); + lea(end, Address(obj, con_size_in_bytes)); } else { - if (oop_extra_words > 0) { - addptr(var_size_in_bytes, oop_extra_words * HeapWordSize); - } lea(end, Address(obj, var_size_in_bytes, Address::times_1)); } cmpptr(end, Address(thread, JavaThread::tlab_end_offset())); @@ -4625,8 +4485,6 @@ // update the tlab top pointer movptr(Address(thread, JavaThread::tlab_top_offset()), end); - Universe::heap()->compile_prepare_oop(this, obj); - // recover var_size_in_bytes if necessary if (var_size_in_bytes == end) { subptr(var_size_in_bytes, obj); @@ -5400,23 +5258,6 @@ BLOCK_COMMENT("} verify_oop"); } -#if INCLUDE_ALL_GCS -void MacroAssembler::in_heap_check(Register raddr, Register tmp, Label& done) { - ShenandoahHeap *h = (ShenandoahHeap *)Universe::heap(); - - HeapWord* heap_base = (HeapWord*) h->base(); - HeapWord* last_region_end = heap_base + (ShenandoahHeapRegion::region_size_bytes() / HeapWordSize) * h->num_regions(); - guarantee(heap_base < last_region_end, err_msg("sanity: %p < %p", heap_base, last_region_end)); - movptr(tmp, (intptr_t) heap_base); - cmpptr(raddr, tmp); - jcc(Assembler::below, done); - movptr(tmp, (intptr_t) last_region_end); - cmpptr(raddr, tmp); - jcc(Assembler::aboveEqual, done); - -} -#endif - RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) { @@ -5953,6 +5794,12 @@ } else #endif movptr(dst, src); + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + ShenandoahBarrierSetAssembler::bsasm()->load_reference_barrier(this, dst); + } +#endif } // Doesn't do verfication, generates fixed size code @@ -5964,6 +5811,12 @@ } else #endif movptr(dst, src); + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + ShenandoahBarrierSetAssembler::bsasm()->load_reference_barrier(this, dst); + } +#endif } void MacroAssembler::store_heap_oop(Address dst, Register src) { @@ -7077,11 +6930,7 @@ int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); // Check the input args - if (is_array_equ) { - cmpoops(ary1, ary2); - } else { - cmpptr(ary1, ary2); - } + cmpptr(ary1, ary2); jcc(Assembler::equal, TRUE_LABEL); if (is_array_equ) { @@ -8763,23 +8612,3 @@ SkipIfEqual::~SkipIfEqual() { _masm->bind(_label); } - -void MacroAssembler::cmpoops(Register src1, Register src2) { - cmpptr(src1, src2); - oopDesc::bs()->asm_acmp_barrier(this, src1, src2); -} - -void MacroAssembler::cmpoops(Register src1, Address src2) { - cmpptr(src1, src2); -#if INCLUDE_ALL_GCS - if (UseShenandoahGC && ShenandoahAcmpBarrier) { - Label done; - jccb(Assembler::equal, done); - movptr(rscratch2, src2); - oopDesc::bs()->interpreter_read_barrier(this, src1); - oopDesc::bs()->interpreter_read_barrier(this, rscratch2); - cmpptr(src1, rscratch2); - bind(done); - } -#endif -} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/macroAssembler_x86.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -316,8 +316,6 @@ Register tmp, Register tmp2); - void shenandoah_write_barrier(Register dst); - #endif // INCLUDE_ALL_GCS // split store_check(Register obj) to enhance instruction interleaving @@ -756,20 +754,8 @@ // cmp64 to avoild hiding cmpq void cmp64(Register src1, AddressLiteral src); - // Special cmp for heap objects, possibly inserting required barriers. - void cmpoops(Register src1, Register src2); - void cmpoops(Register src1, Address src2); - void cmpxchgptr(Register reg, Address adr); -#if INCLUDE_ALL_GCS - // Special Shenandoah CAS implementation that handles false negatives - // due to concurrent evacuation. - void cmpxchg_oop_shenandoah(Register res, Address addr, Register oldval, Register newval, - bool exchange, - Register tmp1, Register tmp2); -#endif - void locked_cmpxchgptr(Register reg, AddressLiteral adr); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/methodHandles_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/methodHandles_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/methodHandles_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/methodHandles_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -164,13 +164,10 @@ //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); }); // Load the invoker, as MH -> MH.form -> LF.vmentry - oopDesc::bs()->interpreter_read_barrier(_masm, recv); __ verify_oop(recv); __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()))); - oopDesc::bs()->interpreter_read_barrier(_masm, method_temp); __ verify_oop(method_temp); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()))); - oopDesc::bs()->interpreter_read_barrier(_masm, method_temp); __ verify_oop(method_temp); // the following assumes that a Method* is normally compressed in the vmtarget field: __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()))); @@ -182,11 +179,10 @@ Address(temp2, ConstMethod::size_of_parameters_offset()), sizeof(u2), /*is_signed*/ false); // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); - __ movptr(temp2, __ argument_address(temp2, -1)); Label L; - __ cmpoops(recv, temp2); + __ cmpptr(recv, __ argument_address(temp2, -1)); __ jcc(Assembler::equal, L); - __ movptr(rax, temp2); + __ movptr(rax, __ argument_address(temp2, -1)); __ STOP("receiver not on stack"); __ BIND(L); } @@ -379,7 +375,6 @@ // rsi/r13 - interpreter linkage (if interpreted) // rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled) - oopDesc::bs()->interpreter_read_barrier(_masm, member_reg); Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/sharedRuntime_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/sharedRuntime_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/sharedRuntime_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -2386,7 +2386,6 @@ // Load the oop from the handle __ movptr(obj_reg, Address(oop_handle_reg, 0)); - oopDesc::bs()->interpreter_write_barrier(masm, obj_reg); if (UseBiasedLocking) { __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock); } @@ -2568,7 +2567,6 @@ // Get locked oop from the handle we passed to jni __ movptr(obj_reg, Address(oop_handle_reg, 0)); - oopDesc::bs()->interpreter_write_barrier(masm, obj_reg); Label done; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_MacroAssembler.hpp" +#include "c1/c1_LIRAssembler.hpp" +#include "macroAssembler_x86.hpp" +#include "shenandoahBarrierSetAssembler_x86.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" +#include "gc_implementation/shenandoah/shenandoahRuntime.hpp" +#include "runtime/stubCodeGenerator.hpp" + +ShenandoahBarrierSetAssembler* ShenandoahBarrierSetAssembler::bsasm() { + return ShenandoahBarrierSet::barrier_set()->bsasm(); +} + +#define __ masm-> + +void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) { + assert(ShenandoahCASBarrier, "should be enabled"); + Label is_null; + __ testptr(dst, dst); + __ jcc(Assembler::zero, is_null); + resolve_forward_pointer_not_null(masm, dst, tmp); + __ bind(is_null); +} + +void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) { + assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled"); + // The below loads the mark word, checks if the lowest two bits are + // set, and if so, clear the lowest two bits and copy the result + // to dst. Otherwise it leaves dst alone. + // Implementing this is surprisingly awkward. I do it here by: + // - Inverting the mark word + // - Test lowest two bits == 0 + // - If so, set the lowest two bits + // - Invert the result back, and copy to dst + + bool borrow_reg = (tmp == noreg); + if (borrow_reg) { + // No free registers available. Make one useful. + tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx); + if (tmp == dst) { + tmp = LP64_ONLY(rscratch2) NOT_LP64(rcx); + } + __ push(tmp); + } + + assert_different_registers(dst, tmp); + + Label done; + __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes())); + __ notptr(tmp); + __ testb(tmp, markOopDesc::marked_value); + __ jccb(Assembler::notZero, done); + __ orptr(tmp, markOopDesc::marked_value); + __ notptr(tmp); + __ mov(dst, tmp); + __ bind(done); + + if (borrow_reg) { + __ pop(tmp); + } +} + +void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) { + assert(ShenandoahLoadRefBarrier, "Should be enabled"); + + Label done; + +#ifdef _LP64 + Register thread = r15_thread; +#else + Register thread = rcx; + if (thread == dst) { + thread = rbx; + } + __ push(thread); + __ get_thread(thread); +#endif + assert_different_registers(dst, thread); + + Address gc_state(thread, in_bytes(JavaThread::gc_state_offset())); + __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED); + __ jcc(Assembler::zero, done); + + { + __ save_vector_registers(); + + __ subptr(rsp, LP64_ONLY(16) NOT_LP64(8) * wordSize); + + __ movptr(Address(rsp, 0 * wordSize), rax); + __ movptr(Address(rsp, 1 * wordSize), rcx); + __ movptr(Address(rsp, 2 * wordSize), rdx); + __ movptr(Address(rsp, 3 * wordSize), rbx); + // skip rsp + __ movptr(Address(rsp, 5 * wordSize), rbp); + __ movptr(Address(rsp, 6 * wordSize), rsi); + __ movptr(Address(rsp, 7 * wordSize), rdi); +#ifdef _LP64 + __ movptr(Address(rsp, 8 * wordSize), r8); + __ movptr(Address(rsp, 9 * wordSize), r9); + __ movptr(Address(rsp, 10 * wordSize), r10); + __ movptr(Address(rsp, 11 * wordSize), r11); + __ movptr(Address(rsp, 12 * wordSize), r12); + __ movptr(Address(rsp, 13 * wordSize), r13); + __ movptr(Address(rsp, 14 * wordSize), r14); + __ movptr(Address(rsp, 15 * wordSize), r15); +#endif + } + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_interpreter), dst); + { +#ifdef _LP64 + __ movptr(r15, Address(rsp, 15 * wordSize)); + __ movptr(r14, Address(rsp, 14 * wordSize)); + __ movptr(r13, Address(rsp, 13 * wordSize)); + __ movptr(r12, Address(rsp, 12 * wordSize)); + __ movptr(r11, Address(rsp, 11 * wordSize)); + __ movptr(r10, Address(rsp, 10 * wordSize)); + __ movptr(r9, Address(rsp, 9 * wordSize)); + __ movptr(r8, Address(rsp, 8 * wordSize)); +#endif + __ movptr(rdi, Address(rsp, 7 * wordSize)); + __ movptr(rsi, Address(rsp, 6 * wordSize)); + __ movptr(rbp, Address(rsp, 5 * wordSize)); + // skip rsp + __ movptr(rbx, Address(rsp, 3 * wordSize)); + __ movptr(rdx, Address(rsp, 2 * wordSize)); + __ movptr(rcx, Address(rsp, 1 * wordSize)); + if (dst != rax) { + __ movptr(dst, rax); + __ movptr(rax, Address(rsp, 0 * wordSize)); + } + __ addptr(rsp, LP64_ONLY(16) NOT_LP64(8) * wordSize); + + __ restore_vector_registers(); + } + __ bind(done); + +#ifndef _LP64 + __ pop(thread); +#endif +} + +void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { + if (ShenandoahStoreValEnqueueBarrier) { + storeval_barrier_impl(masm, dst, tmp); + } +} + +void ShenandoahBarrierSetAssembler::storeval_barrier_impl(MacroAssembler* masm, Register dst, Register tmp) { + assert(ShenandoahStoreValEnqueueBarrier, "should be enabled"); + + if (dst == noreg) return; + + if (ShenandoahStoreValEnqueueBarrier) { + // The set of registers to be saved+restored is the same as in the write-barrier above. + // Those are the commonly used registers in the interpreter. + __ pusha(); + // __ push_callee_saved_registers(); + __ subptr(rsp, 2 * Interpreter::stackElementSize); + __ movdbl(Address(rsp, 0), xmm0); + +#ifdef _LP64 + Register thread = r15_thread; +#else + Register thread = rcx; + if (thread == dst || thread == tmp) { + thread = rdi; + } + if (thread == dst || thread == tmp) { + thread = rbx; + } + __ get_thread(thread); +#endif + assert_different_registers(dst, tmp, thread); + + __ g1_write_barrier_pre(noreg, dst, thread, tmp, true, false); + __ movdbl(xmm0, Address(rsp, 0)); + __ addptr(rsp, 2 * Interpreter::stackElementSize); + //__ pop_callee_saved_registers(); + __ popa(); + } +} + +void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) { + if (ShenandoahLoadRefBarrier) { + Label done; + __ testptr(dst, dst); + __ jcc(Assembler::zero, done); + load_reference_barrier_not_null(masm, dst); + __ bind(done); + } +} + +// Special Shenandoah CAS implementation that handles false negatives +// due to concurrent evacuation. +void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, + Register res, Address addr, Register oldval, Register newval, + bool exchange, Register tmp1, Register tmp2) { + assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled"); + assert(oldval == rax, "must be in rax for implicit use in cmpxchg"); + + Label retry, done; + + // Remember oldval for retry logic below +#ifdef _LP64 + if (UseCompressedOops) { + __ movl(tmp1, oldval); + } else +#endif + { + __ movptr(tmp1, oldval); + } + + // Step 1. Try to CAS with given arguments. If successful, then we are done, + // and can safely return. + if (os::is_MP()) __ lock(); +#ifdef _LP64 + if (UseCompressedOops) { + __ cmpxchgl(newval, addr); + } else +#endif + { + __ cmpxchgptr(newval, addr); + } + __ jcc(Assembler::equal, done, true); + + // Step 2. CAS had failed. This may be a false negative. + // + // The trouble comes when we compare the to-space pointer with the from-space + // pointer to the same object. To resolve this, it will suffice to resolve both + // oldval and the value from memory -- this will give both to-space pointers. + // If they mismatch, then it was a legitimate failure. + // +#ifdef _LP64 + if (UseCompressedOops) { + __ decode_heap_oop(tmp1); + } +#endif + resolve_forward_pointer(masm, tmp1); + +#ifdef _LP64 + if (UseCompressedOops) { + __ movl(tmp2, oldval); + __ decode_heap_oop(tmp2); + } else +#endif + { + __ movptr(tmp2, oldval); + } + resolve_forward_pointer(masm, tmp2); + + __ cmpptr(tmp1, tmp2); + __ jcc(Assembler::notEqual, done, true); + + // Step 3. Try to CAS again with resolved to-space pointers. + // + // Corner case: it may happen that somebody stored the from-space pointer + // to memory while we were preparing for retry. Therefore, we can fail again + // on retry, and so need to do this in loop, always resolving the failure + // witness. + __ bind(retry); + if (os::is_MP()) __ lock(); +#ifdef _LP64 + if (UseCompressedOops) { + __ cmpxchgl(newval, addr); + } else +#endif + { + __ cmpxchgptr(newval, addr); + } + __ jcc(Assembler::equal, done, true); + +#ifdef _LP64 + if (UseCompressedOops) { + __ movl(tmp2, oldval); + __ decode_heap_oop(tmp2); + } else +#endif + { + __ movptr(tmp2, oldval); + } + resolve_forward_pointer(masm, tmp2); + + __ cmpptr(tmp1, tmp2); + __ jcc(Assembler::equal, retry, true); + + // Step 4. If we need a boolean result out of CAS, check the flag again, + // and promote the result. Note that we handle the flag from both the CAS + // itself and from the retry loop. + __ bind(done); + if (!exchange) { + assert(res != NULL, "need result register"); +#ifdef _LP64 + __ setb(Assembler::equal, res); + __ movzbl(res, res); +#else + // Need something else to clean the result, because some registers + // do not have byte encoding that movzbl wants. Cannot do the xor first, + // because it modifies the flags. + Label res_non_zero; + __ movptr(res, 1); + __ jcc(Assembler::equal, res_non_zero, true); + __ xorptr(res, res); + __ bind(res_non_zero); +#endif + } +} + +#undef __ + +#ifdef COMPILER1 + +#define __ ce->masm()-> + +void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub) { + __ bind(*stub->entry()); + + Label done; + Register obj = stub->obj()->as_register(); + Register res = stub->result()->as_register(); + + if (res != obj) { + __ mov(res, obj); + } + + // Check for null. + if (stub->needs_null_check()) { + __ testptr(res, res); + __ jcc(Assembler::zero, done); + } + + load_reference_barrier_not_null(ce->masm(), res); + + __ bind(done); + __ jmp(*stub->continuation()); +} + +#undef __ + +#endif // COMPILER1 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_X86_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_X86_HPP +#define CPU_X86_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_X86_HPP + +#include "asm/macroAssembler.hpp" +#include "memory/allocation.hpp" +#ifdef COMPILER1 +class LIR_Assembler; +class ShenandoahLoadReferenceBarrierStub; +class StubAssembler; +class StubCodeGenerator; +#endif + +class ShenandoahBarrierSetAssembler : public CHeapObj { +private: + + void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg); + void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg); + + void load_reference_barrier_not_null(MacroAssembler* masm, Register dst); + + void storeval_barrier_impl(MacroAssembler* masm, Register dst, Register tmp); + +public: + static ShenandoahBarrierSetAssembler* bsasm(); + + void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp); +#ifdef COMPILER1 + void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub); +#endif + + void load_reference_barrier(MacroAssembler* masm, Register dst); + + virtual void cmpxchg_oop(MacroAssembler* masm, + Register res, Address addr, Register oldval, Register newval, + bool exchange, Register tmp1, Register tmp2); +}; + +#endif // CPU_X86_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_X86_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSet_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSet_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSet_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/shenandoahBarrierSet_x86.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" - -#include "asm/macroAssembler.hpp" -#include "interpreter/interpreter.hpp" - -#define __ masm-> - -#ifndef CC_INTERP - -void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { - if (ShenandoahReadBarrier) { - Label is_null; - __ testptr(dst, dst); - __ jcc(Assembler::zero, is_null); - interpreter_read_barrier_not_null(masm, dst); - __ bind(is_null); - } -} - -void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - if (ShenandoahReadBarrier) { - __ movptr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset())); - } -} - -void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { - if (! ShenandoahWriteBarrier) { - return interpreter_read_barrier(masm, dst); - } - -#ifdef _LP64 - assert(dst != rscratch1, "different regs"); - - Label done; - - Address gc_state(r15_thread, in_bytes(JavaThread::gc_state_offset())); - - // Now check if evacuation is in progress. - __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - __ jcc(Assembler::zero, done); - - // Heap is unstable, need to perform the read-barrier even if WB is inactive - interpreter_read_barrier_not_null(masm, dst); - - __ testb(gc_state, ShenandoahHeap::EVACUATION); - __ jcc(Assembler::zero, done); - __ push(rscratch1); - __ push(rscratch2); - - __ movptr(rscratch1, dst); - __ shrptr(rscratch1, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - __ movptr(rscratch2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr()); - __ movbool(rscratch2, Address(rscratch2, rscratch1, Address::times_1)); - __ testb(rscratch2, 0x1); - - __ pop(rscratch2); - __ pop(rscratch1); - - __ jcc(Assembler::zero, done); - - __ push(rscratch1); - - // Save possibly live regs. - if (dst != rax) { - __ push(rax); - } - if (dst != rbx) { - __ push(rbx); - } - if (dst != rcx) { - __ push(rcx); - } - if (dst != rdx) { - __ push(rdx); - } - if (dst != c_rarg1) { - __ push(c_rarg1); - } - - __ subptr(rsp, 2 * wordSize); - __ movdbl(Address(rsp, 0), xmm0); - - // Call into runtime - __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_IRT), dst); - __ mov(rscratch1, rax); - - // Restore possibly live regs. - __ movdbl(xmm0, Address(rsp, 0)); - __ addptr(rsp, 2 * Interpreter::stackElementSize); - - if (dst != c_rarg1) { - __ pop(c_rarg1); - } - if (dst != rdx) { - __ pop(rdx); - } - if (dst != rcx) { - __ pop(rcx); - } - if (dst != rbx) { - __ pop(rbx); - } - if (dst != rax) { - __ pop(rax); - } - - // Move result into dst reg. - __ mov(dst, rscratch1); - - __ pop(rscratch1); - - __ bind(done); -#else - Unimplemented(); -#endif -} - -void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { - assert (UseShenandoahGC, "Should be enabled"); - if (ShenandoahAcmpBarrier) { - Label done; - __ jccb(Assembler::equal, done); - interpreter_read_barrier(masm, op1); - interpreter_read_barrier(masm, op2); - __ cmpptr(op1, op2); - __ bind(done); - } -} - -void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { -#ifdef _LP64 - __ incrementq(obj, ShenandoahBrooksPointer::byte_size()); -#else - __ incrementl(obj, ShenandoahBrooksPointer::byte_size()); -#endif - __ movptr(Address(obj, ShenandoahBrooksPointer::byte_offset()), obj); -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_32.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_32.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -38,6 +38,7 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" +#include "utilities/macros.hpp" #include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" @@ -708,6 +709,7 @@ switch (bs->kind()) { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: + case BarrierSet::ShenandoahBarrierSet: // With G1, don't generate the call if we statically know that the target in uninitialized if (!uninitialized_target) { __ pusha(); // push registers @@ -741,6 +743,7 @@ switch (bs->kind()) { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: + case BarrierSet::ShenandoahBarrierSet: { __ pusha(); // push registers __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), @@ -1484,12 +1487,30 @@ __ BIND(L_store_element); __ movptr(to_element_addr, elem); // store the oop __ increment(count); // increment the count toward zero +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Shenandoah barrier is too big for 8-bit offsets to work + __ jcc(Assembler::zero, L_do_card_marks); + } else +#endif __ jccb(Assembler::zero, L_do_card_marks); // ======== loop entry is here ======== __ BIND(L_load_element); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(elem, from_element_addr); + } else +#endif __ movptr(elem, from_element_addr); // load the oop __ testptr(elem, elem); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Shenandoah barrier is too big for 8-bit offsets to work + __ jcc(Assembler::zero, L_store_element); + } else +#endif __ jccb(Assembler::zero, L_store_element); // (Could do a trick here: Remember last successful non-null @@ -2719,6 +2740,169 @@ return start; } + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data(0x0b0a0908, relocInfo::none, 0); + __ emit_data(0x0f0e0d0c, relocInfo::none, 0); + __ emit_data(0x03020100, relocInfo::none, 0); + __ emit_data(0x07060504, relocInfo::none, 0); + + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data(0x0c0d0e0f, relocInfo::none, 0); + __ emit_data(0x08090a0b, relocInfo::none, 0); + __ emit_data(0x04050607, relocInfo::none, 0); + __ emit_data(0x00010203, relocInfo::none, 0); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support"); + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = rdi; + const Register subkeyH = rsi; + const Register data = rdx; + const Register blocks = rcx; + + const Address state_param(rbp, 8+0); + const Address subkeyH_param(rbp, 8+4); + const Address data_param(rbp, 8+8); + const Address blocks_param(rbp, 8+12); + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + + __ enter(); + handleSOERegisters(true); // Save registers + + __ movptr(state, state_param); + __ movptr(subkeyH, subkeyH_param); + __ movptr(data, data_param); + __ movptr(blocks, blocks_param); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp6); + __ pslld (xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp4, 31); + __ movdqu(xmm_temp5, xmm_temp7); + __ pslldq(xmm_temp4, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp5, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp4); + __ por(xmm_temp6, xmm_temp5); + + // + // First phase of the reduction + // + // Move xmm3 into xmm4, xmm5, xmm7 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp4, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp5, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp5); + __ movdqu(xmm_temp4, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp4, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm5, xmm7 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp7, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp7); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp4); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + // Byte swap 16-byte result + __ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + __ movdqu(Address(state, 0), xmm_temp6); // store the result + + handleSOERegisters(false); // restore registers + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -3018,6 +3202,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,10 +25,6 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_x86.hpp" #include "oops/instanceOop.hpp" @@ -46,6 +42,9 @@ #ifdef COMPILER2 #include "opto/runtime.hpp" #endif +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif // Declaration and definition of StubGenerator (no .hpp file). // For a more detailed description of the stub routine structure @@ -756,95 +755,6 @@ return start; } - address generate_shenandoah_wb(bool c_abi, bool do_cset_test) { - StubCodeMark mark(this, "StubRoutines", "shenandoah_wb"); - address start = __ pc(); - - Label not_done; - - // We use RDI, which also serves as argument register for slow call. - // RAX always holds the src object ptr, except after the slow call and - // the cmpxchg, then it holds the result. - // R8 and RCX are used as temporary registers. - if (!c_abi) { - __ push(rdi); - __ push(r8); - } - - // Check for object beeing in the collection set. - // TODO: Can we use only 1 register here? - // The source object arrives here in rax. - // live: rax - // live: rdi - if (!c_abi) { - __ mov(rdi, rax); - } else { - if (rax != c_rarg0) { - __ mov(rax, c_rarg0); - } - } - if (do_cset_test) { - __ shrptr(rdi, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - // live: r8 - __ movptr(r8, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr()); - __ movbool(r8, Address(r8, rdi, Address::times_1)); - // unlive: rdi - __ testbool(r8); - // unlive: r8 - __ jccb(Assembler::notZero, not_done); - - if (!c_abi) { - __ pop(r8); - __ pop(rdi); - } - __ ret(0); - - __ bind(not_done); - } - - if (!c_abi) { - __ push(rcx); - } - - if (!c_abi) { - __ push(rdx); - __ push(rdi); - __ push(rsi); - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); - __ push(r12); - __ push(r13); - __ push(r14); - __ push(r15); - } - __ save_vector_registers(); - __ movptr(rdi, rax); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_JRT), rdi); - __ restore_vector_registers(); - if (!c_abi) { - __ pop(r15); - __ pop(r14); - __ pop(r13); - __ pop(r12); - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); - __ pop(rsi); - __ pop(rdi); - __ pop(rdx); - - __ pop(rcx); - __ pop(r8); - __ pop(rdi); - } - __ ret(0); - - return start; - } - address generate_f2i_fixup() { StubCodeMark mark(this, "StubRoutines", "f2i_fixup"); Address inout(rsp, 5 * wordSize); // return address + 4 saves @@ -3734,6 +3644,175 @@ return start; } + + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data64(0x0f0e0d0c0b0a0908, relocInfo::none ); + __ emit_data64(0x0706050403020100, relocInfo::none ); + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none ); + __ emit_data64(0x0001020304050607, relocInfo::none ); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = c_rarg0; + const Register subkeyH = c_rarg1; + const Register data = c_rarg2; + const Register blocks = c_rarg3; + +#ifdef _WIN64 + const int XMM_REG_LAST = 10; +#endif + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + const XMMRegister xmm_temp8 = xmm8; + const XMMRegister xmm_temp9 = xmm9; + const XMMRegister xmm_temp10 = xmm10; + + __ enter(); + +#ifdef _WIN64 + // save the xmm registers which must be preserved 6-10 + __ subptr(rsp, -rsp_after_call_off * wordSize); + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(xmm_save(i), as_XMMRegister(i)); + } +#endif + + __ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, xmm_temp10); + + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, xmm_temp10); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp6); + __ pslld(xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp8, 31); + __ movdqu(xmm_temp9, xmm_temp7); + __ pslldq(xmm_temp8, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp9, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp8); + __ por(xmm_temp6, xmm_temp9); + + // + // First phase of the reduction + // + // Move xmm3 into xmm7, xmm8, xmm9 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp3); + __ movdqu(xmm_temp9, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp8, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp9, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp8); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp9); + __ movdqu(xmm_temp8, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp8, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm4, xmm5 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp4, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp8); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + __ pshufb(xmm_temp6, xmm_temp10); // Byte swap 16-byte result + __ movdqu(Address(state, 0), xmm_temp6); // store the result + +#ifdef _WIN64 + // restore xmm regs belonging to calling function + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(as_XMMRegister(i), xmm_save(i)); + } +#endif + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -4144,10 +4223,6 @@ throw_NullPointerException_at_call)); // entry points that are platform specific - if (UseShenandoahGC && ShenandoahWriteBarrier) { - StubRoutines::x86::_shenandoah_wb = generate_shenandoah_wb(false, true); - StubRoutines::_shenandoah_wb_C = generate_shenandoah_wb(true, false); - } StubRoutines::x86::_f2i_fixup = generate_f2i_fixup(); StubRoutines::x86::_f2l_fixup = generate_f2l_fixup(); StubRoutines::x86::_d2i_fixup = generate_d2i_fixup(); @@ -4176,6 +4251,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,7 +34,6 @@ address StubRoutines::x86::_get_previous_fp_entry = NULL; address StubRoutines::x86::_get_previous_sp_entry = NULL; -address StubRoutines::x86::_shenandoah_wb = NULL; address StubRoutines::x86::_f2i_fixup = NULL; address StubRoutines::x86::_f2l_fixup = NULL; address StubRoutines::x86::_d2i_fixup = NULL; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86_64.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,8 +32,8 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } enum platform_dependent_constants { - code_size1 = 30000, // simply increase if too small (assembler will crash if too small) - code_size2 = 46700 // simply increase if too small (assembler will crash if too small) + code_size1 = 19000, // simply increase if too small (assembler will crash if too small) + code_size2 = 24000 // simply increase if too small (assembler will crash if too small) }; class x86 { @@ -43,7 +43,6 @@ static address _get_previous_fp_entry; static address _get_previous_sp_entry; - static address _shenandoah_wb; static address _f2i_fixup; static address _f2l_fixup; static address _d2i_fixup; @@ -66,11 +65,6 @@ return _get_previous_sp_entry; } - static address shenandoah_wb() - { - return _shenandoah_wb; - } - static address f2i_fixup() { return _f2i_fixup; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -33,6 +33,8 @@ address StubRoutines::x86::_verify_mxcsr_entry = NULL; address StubRoutines::x86::_key_shuffle_mask_addr = NULL; +address StubRoutines::x86::_ghash_long_swap_mask_addr = NULL; +address StubRoutines::x86::_ghash_byte_swap_mask_addr = NULL; uint64_t StubRoutines::x86::_crc_by128_masks[] = { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/stubRoutines_x86.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,10 +36,15 @@ // masks and table for CRC32 static uint64_t _crc_by128_masks[]; static juint _crc_table[]; + // swap mask for ghash + static address _ghash_long_swap_mask_addr; + static address _ghash_byte_swap_mask_addr; public: static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } static address crc_by128_masks_addr() { return (address)_crc_by128_masks; } + static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; } + static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; } #endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_32.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_32.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_32.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -746,6 +746,21 @@ __ jmp(xreturn_path); __ bind(notChar); + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + Label notObj; + + // Needs GC barriers + __ cmpl(rdx, atos); + __ jcc(Assembler::notEqual, notObj); + __ load_heap_oop(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notObj); + } +#endif + #ifdef ASSERT Label okay; __ cmpl(rdx, atos); @@ -814,7 +829,7 @@ const int referent_offset = java_lang_ref_Reference::referent_offset; guarantee(referent_offset > 0, "referent offset not initialized"); - if (UseG1GC) { + if (UseG1GC || UseShenandoahGC) { Label slow_path; // Check if local 0 != NULL @@ -838,10 +853,17 @@ // Load the value of the referent field. const Address field_address(rax, referent_offset); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(rax, field_address); + } else +#endif __ movptr(rax, field_address); // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. + if (!UseShenandoahGC || ShenandoahKeepAliveBarrier) { __ get_thread(rcx); __ g1_write_barrier_pre(noreg /* obj */, rax /* pre_val */, @@ -849,6 +871,7 @@ rbx /* tmp */, true /* tosca_save */, true /* expand_call */); + } // _areturn __ pop(rsi); // get sender sp diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateInterpreter_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -542,7 +542,6 @@ #endif // ASSERT __ bind(done); - oopDesc::bs()->interpreter_write_barrier(_masm, rax); } // add space for monitor & lock @@ -681,8 +680,6 @@ ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rax); - Label notObj, notInt, notByte, notBool, notShort; const Address field_address(rax, rcx, Address::times_1); @@ -804,8 +801,6 @@ __ testptr(rax, rax); __ jcc(Assembler::zero, slow_path); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rax); - // rax: local 0 // rbx: method (but can be used as scratch now) // rdx: scratch @@ -820,12 +815,14 @@ // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. + if (!UseShenandoahGC || ShenandoahKeepAliveBarrier) { __ g1_write_barrier_pre(noreg /* obj */, rax /* pre_val */, r15_thread /* thread */, rbx /* tmp */, true /* tosca_live */, true /* expand_call */); + } // _areturn __ pop(rdi); // get return address @@ -936,7 +933,6 @@ __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC } else { __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, buf); __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset __ addq(buf, off); // + offset diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_32.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_32.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_32.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_32.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -36,6 +36,9 @@ #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" #include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif #ifndef CC_INTERP #define __ _masm-> @@ -165,6 +168,41 @@ } break; + case BarrierSet::ShenandoahBarrierSet: + { + // flatten object address if needed + // We do it regardless of precise because we need the registers + if (obj.index() == noreg && obj.disp() == 0) { + if (obj.base() != rdx) { + __ movl(rdx, obj.base()); + } + } else { + __ leal(rdx, obj); + } + __ get_thread(rcx); + __ save_bcp(); + if (ShenandoahSATBBarrier) { + __ g1_write_barrier_pre(rdx /* obj */, + rbx /* pre_val */, + rcx /* thread */, + rsi /* tmp */, + val != noreg /* tosca_live */, + false /* expand_call */); + } + + // Do the actual store + // noreg means NULL + if (val == noreg) { + __ movptr(Address(rdx, 0), NULL_WORD); + // No post barrier for NULL + } else { + ShenandoahBarrierSetAssembler::bsasm()->storeval_barrier(_masm, val, rsi); + __ movl(Address(rdx, 0), val); + } + __ restore_bcp(); + + } + break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: @@ -668,7 +706,14 @@ // rdx: array index_check(rdx, rax); // kills rbx, // rax,: index +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(rax, Address(rdx, rax, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + } else +#endif __ movptr(rax, Address(rdx, rax, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + } @@ -2303,6 +2348,12 @@ __ cmpl(flags, atos ); __ jcc(Assembler::notEqual, notObj); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(rax, lo); + } else +#endif __ movl(rax, lo ); __ push(atos); if (!is_static) { @@ -2871,7 +2922,16 @@ case Bytecodes::_fast_lgetfield: __ stop("should not be rewritten"); break; case Bytecodes::_fast_fgetfield: __ fld_s(lo); break; case Bytecodes::_fast_dgetfield: __ fld_d(lo); break; - case Bytecodes::_fast_agetfield: __ movptr(rax, lo); __ verify_oop(rax); break; + case Bytecodes::_fast_agetfield: +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(rax, lo); + } else +#endif + __ movptr(rax, lo); + __ verify_oop(rax); + break; default: ShouldNotReachHere(); } @@ -2897,6 +2957,12 @@ if (state == itos) { __ movl(rax, lo); } else if (state == atos) { +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Needs GC barriers + __ load_heap_oop(rax, lo); + } else +#endif __ movptr(rax, lo); __ verify_oop(rax); } else if (state == ftos) { @@ -2952,6 +3018,12 @@ if (is_invokedynamic || is_invokehandle) { Label L_no_push; __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift)); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + // Shenandoah barrier is too large to make short jump. + __ jcc(Assembler::zero, L_no_push); + } else +#endif __ jccb(Assembler::zero, L_no_push); // Push the appendix as a trailing parameter. // This must be done before we get the receiver, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_64.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/templateTable_x86_64.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -36,6 +36,9 @@ #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" #include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif #ifndef CC_INTERP @@ -140,7 +143,6 @@ #if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: - case BarrierSet::ShenandoahBarrierSet: { // flatten object address if needed if (obj.index() == noreg && obj.disp() == 0) { @@ -165,9 +167,6 @@ new_val = rbx; __ movptr(new_val, val); } - // For Shenandoah, make sure we only store refs into to-space. - oopDesc::bs()->interpreter_read_barrier(_masm, val); - __ store_heap_oop(Address(rdx, 0), val); __ g1_write_barrier_post(rdx /* store_adr */, new_val /* new_val */, @@ -177,6 +176,32 @@ } } break; + case BarrierSet::ShenandoahBarrierSet: + { + // flatten object address if needed + if (obj.index() == noreg && obj.disp() == 0) { + if (obj.base() != rdx) { + __ movq(rdx, obj.base()); + } + } else { + __ leaq(rdx, obj); + } + if (ShenandoahSATBBarrier) { + __ g1_write_barrier_pre(rdx /* obj */, + rbx /* pre_val */, + r15_thread /* thread */, + r8 /* tmp */, + val != noreg /* tosca_live */, + false /* expand_call */); + } + if (val == noreg) { + __ store_heap_oop_null(Address(rdx, 0)); + } else { + ShenandoahBarrierSetAssembler::bsasm()->storeval_barrier(_masm, val, r8); + __ store_heap_oop(Address(rdx, 0), val); + } + } + break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: @@ -612,7 +637,6 @@ void TemplateTable::index_check(Register array, Register index) { // destroys rbx // check array - __ null_check(array, arrayOopDesc::length_offset_in_bytes()); // sign extend index for use by indexed load __ movl2ptr(index, index); @@ -633,7 +657,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ movl(rax, Address(rdx, rax, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -644,7 +667,6 @@ __ pop_ptr(rdx); // eax: index // rdx: array - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); index_check(rdx, rax); // kills rbx __ movq(rax, Address(rdx, rbx, Address::times_8, @@ -657,7 +679,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ movflt(xmm0, Address(rdx, rax, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_FLOAT))); @@ -669,7 +690,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ movdbl(xmm0, Address(rdx, rax, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_DOUBLE))); @@ -681,7 +701,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ load_heap_oop(rax, Address(rdx, rax, UseCompressedOops ? Address::times_4 : Address::times_8, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); @@ -693,7 +712,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, @@ -706,7 +724,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, @@ -724,7 +741,6 @@ // rdx: array __ pop_ptr(rdx); index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, @@ -737,7 +753,6 @@ // eax: index // rdx: array index_check(rdx, rax); // kills rbx - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rdx); __ load_signed_short(rax, Address(rdx, rax, Address::times_2, @@ -922,7 +937,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); __ movl(Address(rdx, rbx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_INT)), @@ -937,7 +951,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); __ movq(Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG)), @@ -952,7 +965,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); __ movflt(Address(rdx, rbx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_FLOAT)), @@ -967,7 +979,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); __ movdbl(Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)), @@ -987,7 +998,6 @@ arrayOopDesc::base_offset_in_bytes(T_OBJECT)); index_check(rdx, rcx); // kills rbx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); // do array store check - check for NULL value first __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); @@ -1038,7 +1048,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); // Need to check whether array is boolean or byte // since both types share the bastore bytecode. __ load_klass(rcx, rdx); @@ -1063,7 +1072,6 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx - oopDesc::bs()->interpreter_write_barrier(_masm, rdx); __ movw(Address(rdx, rbx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)), @@ -1869,7 +1877,7 @@ // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(rdx); - __ cmpoops(rdx, rax); + __ cmpptr(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -2326,7 +2334,6 @@ // obj is on the stack pop_and_check_object(obj); } - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, obj); const Address field(obj, off, Address::times_1); @@ -2565,7 +2572,6 @@ { __ pop(btos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movb(field, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no); @@ -2581,7 +2587,6 @@ { __ pop(ztos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ andl(rax, 0x1); __ movb(field, rax); if (!is_static) { @@ -2598,7 +2603,6 @@ { __ pop(atos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); // Store into the field do_oop_store(_masm, field, rax, _bs->kind(), false); if (!is_static) { @@ -2615,7 +2619,6 @@ { __ pop(itos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movl(field, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no); @@ -2631,7 +2634,6 @@ { __ pop(ctos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movw(field, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no); @@ -2647,7 +2649,6 @@ { __ pop(stos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movw(field, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no); @@ -2663,7 +2664,6 @@ { __ pop(ltos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movq(field, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no); @@ -2679,7 +2679,6 @@ { __ pop(ftos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movflt(field, xmm0); if (!is_static) { patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no); @@ -2697,7 +2696,6 @@ { __ pop(dtos); if (!is_static) pop_and_check_object(obj); - oopDesc::bs()->interpreter_write_barrier(_masm, obj); __ movdbl(field, xmm0); if (!is_static) { patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no); @@ -2813,7 +2811,6 @@ // Get object from stack pop_and_check_object(rcx); - oopDesc::bs()->interpreter_write_barrier(_masm, rcx); // field address const Address field(rcx, rbx, Address::times_1); @@ -2903,7 +2900,6 @@ // rax: object __ verify_oop(rax); __ null_check(rax); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rax); Address field(rax, rbx, Address::times_1); // access field @@ -2961,7 +2957,6 @@ // next instruction) __ increment(r13); __ null_check(rax); - oopDesc::bs()->interpreter_read_barrier_not_null(_masm, rax); switch (state) { case itos: __ movl(rax, Address(rax, rbx, Address::times_1)); @@ -3399,17 +3394,11 @@ Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; if (UseTLAB) { - uint oop_extra_words = Universe::heap()->oop_extra_words(); - if (oop_extra_words > 0) { - __ addq(rdx, oop_extra_words * HeapWordSize); - } - __ movptr(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); __ lea(rbx, Address(rax, rdx, Address::times_1)); __ cmpptr(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); __ jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case); __ movptr(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx); - Universe::heap()->compile_prepare_oop(_masm, rax); if (ZeroTLAB) { // the fields have been already cleared __ jmp(initialize_header); @@ -3711,11 +3700,6 @@ // check for NULL object __ null_check(rax); - // We need to preemptively evacuate the object, because we later compare - // it to objects in the BasicObjectLock list, and we might get false negatives - // if another thread evacuates the object in the meantime. See acmp. - oopDesc::bs()->interpreter_write_barrier(_masm, rax); - const Address monitor_block_top( rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( @@ -3810,11 +3794,6 @@ // check for NULL object __ null_check(rax); - // We need to preemptively evacuate the object, because we later compare - // it to objects in the BasicObjectLock list, and we might get false negatives - // if another thread evacuates the object in the meantime. See acmp. - oopDesc::bs()->interpreter_write_barrier(_masm, rax); - const Address monitor_block_top( rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); const Address monitor_block_bot( diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/vm_version_x86.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/vm_version_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/vm_version_x86.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/vm_version_x86.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -553,12 +553,36 @@ // Use AES instructions if available. if (supports_aes()) { if (FLAG_IS_DEFAULT(UseAES)) { - UseAES = true; + FLAG_SET_DEFAULT(UseAES, true); } - } else if (UseAES) { - if (!FLAG_IS_DEFAULT(UseAES)) + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else { + if (UseSSE > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + // The AES intrinsic stubs require AES instruction support (of course) + // but also require sse3 mode or higher for instructions it use. + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("X86 AES intrinsics require SSE3 instructions or higher. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + } + } else if (UseAES || UseAESIntrinsics) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { warning("AES instructions are not available on this CPU"); - FLAG_SET_DEFAULT(UseAES, false); + FLAG_SET_DEFAULT(UseAES, false); + } + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } // Use CLMUL instructions if available. @@ -582,16 +606,15 @@ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); } - // The AES intrinsic stubs require AES instruction support (of course) - // but also require sse3 mode for instructions it use. - if (UseAES && (UseSSE > 2)) { - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - UseAESIntrinsics = true; + // GHASH/GCM intrinsics + if (UseCLMUL && (UseSSE > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; } - } else if (UseAESIntrinsics) { - if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) - warning("AES intrinsics are not available on this CPU"); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } if (UseSHA) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/x86_32.ad openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/x86_32.ad --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/x86_32.ad 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/x86_32.ad 2020-01-13 05:52:26.000000000 +0000 @@ -229,6 +229,11 @@ %} +source_hpp %{ +#if INCLUDE_ALL_GCS +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif +%} //----------SOURCE BLOCK------------------------------------------------------- // This is a block of C++ code which provides values, functions, and @@ -7299,6 +7304,7 @@ %} instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ + predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" @@ -7310,6 +7316,28 @@ ins_pipe( pipe_cmpxchg ); %} +instruct compareAndSwapP_shenandoah(rRegI res, + memory mem_ptr, + eRegP tmp1, eRegP tmp2, + eAXRegP oldval, eCXRegP newval, + eFlagsReg cr) +%{ + predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); + match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); + effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); + + format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} + + ins_encode %{ + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, + $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + false, // swap + $tmp1$$Register, $tmp2$$Register + ); + %} + ins_pipe( pipe_cmpxchg ); +%} + instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/x86_64.ad openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/x86_64.ad --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/x86/vm/x86_64.ad 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/x86/vm/x86_64.ad 2020-01-13 05:52:26.000000000 +0000 @@ -528,7 +528,7 @@ source_hpp %{ #if INCLUDE_ALL_GCS -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#include "shenandoahBarrierSetAssembler_x86.hpp" #endif %} @@ -6427,59 +6427,6 @@ ins_pipe(ialu_reg_reg); // XXX %} -instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{ - match(Set dst (ShenandoahReadBarrier src)); - effect(DEF dst, USE src); - ins_cost(125); // XXX - format %{ "shenandoah_rb $dst, $src" %} - ins_encode %{ -#if INCLUDE_ALL_GCS - Register d = $dst$$Register; - Register s = $src$$Register; - __ movptr(d, Address(s, ShenandoahBrooksPointer::byte_offset())); -#else - ShouldNotReachHere(); -#endif - %} - ins_pipe(ialu_reg_mem); -%} - -instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{ - predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0)); - match(Set dst (ShenandoahReadBarrier (DecodeN src))); - effect(DEF dst, USE src); - ins_cost(125); // XXX - format %{ "shenandoah_rb $dst, $src" %} - ins_encode %{ -#if INCLUDE_ALL_GCS - Register d = $dst$$Register; - Register s = $src$$Register; - __ movptr(d, Address(r12, s, Address::times_1, ShenandoahBrooksPointer::byte_offset())); -#else - ShouldNotReachHere(); -#endif - %} - ins_pipe(ialu_reg_mem); -%} - -instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{ - predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); - match(Set dst (ShenandoahReadBarrier (DecodeN src))); - effect(DEF dst, USE src); - ins_cost(125); // XXX - format %{ "shenandoah_rb $dst, $src" %} - ins_encode %{ -#if INCLUDE_ALL_GCS - Register d = $dst$$Register; - Register s = $src$$Register; - __ movptr(d, Address(r12, s, Address::times_8, ShenandoahBrooksPointer::byte_offset())); -#else - ShouldNotReachHere(); -#endif - %} - ins_pipe(ialu_reg_mem); -%} - // Convert oop pointer into compressed form instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); @@ -7361,7 +7308,7 @@ format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, false, // swap $tmp1$$Register, $tmp2$$Register ); @@ -7452,7 +7399,7 @@ format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, false, // swap $tmp1$$Register, $tmp2$$Register ); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/zero/vm/shenandoahBarrierSet_zero.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/zero/vm/shenandoahBarrierSet_zero.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/cpu/zero/vm/shenandoahBarrierSet_zero.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/cpu/zero/vm/shenandoahBarrierSet_zero.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" - -#include "asm/macroAssembler.hpp" -#include "interpreter/interpreter.hpp" - -#define __ masm-> - -#ifndef CC_INTERP - -void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { - Unimplemented(); -} - -void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { - Unimplemented(); -} - -void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { - Unimplemented(); -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/asm/assembler.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/asm/assembler.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/asm/assembler.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/asm/assembler.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,7 +26,6 @@ #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "asm/codeBuffer.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "runtime/atomic.hpp" #include "runtime/atomic.inline.hpp" #include "runtime/icache.hpp" @@ -301,14 +300,6 @@ bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { // Exception handler checks the nmethod's implicit null checks table // only when this method returns false. -#ifdef AARCH64 - // AArch64 addresses passed from the signal handler may have - // their top 8 bits zeroed. That affects the case where - // Shenandoah tries to load a Brooks pointer via a null oop. - const uintptr_t address_bits = (uintptr_t)0xfffffffffffful; -#else - const uintptr_t address_bits = ~(uintptr_t)0; -#endif #ifdef _LP64 if (UseCompressedOops && Universe::narrow_oop_base() != NULL) { assert (Universe::heap() != NULL, "java heap should be initialized"); @@ -316,21 +307,11 @@ // the 'offset' is equal to [heap_base + offset] for // narrow oop implicit null checks. uintptr_t base = (uintptr_t)Universe::narrow_oop_base(); - int adj = 0; - if (UseShenandoahGC) { - adj = ShenandoahBrooksPointer::byte_offset(); - assert(adj < 0, "no need for positive adjustments"); - } - if ((uintptr_t)((offset - adj) & address_bits) >= base) { + if ((uintptr_t)offset >= base) { // Normalize offset for the next check. offset = (intptr_t)(pointer_delta((void*)offset, (void*)base, 1)); } } #endif - - if (UseShenandoahGC && ((offset & address_bits) == (ShenandoahBrooksPointer::byte_offset() & address_bits))) { - return false; - } - return offset < 0 || os::vm_page_size() <= offset; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRAssembler.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRAssembler.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRAssembler.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRAssembler.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -199,9 +199,6 @@ void emit_opLabel(LIR_OpLabel* op); void emit_arraycopy(LIR_OpArrayCopy* op); void emit_updatecrc32(LIR_OpUpdateCRC32* op); -#if INCLUDE_ALL_GCS - void emit_opShenandoahWriteBarrier(LIR_OpShenandoahWriteBarrier* op); -#endif void emit_opConvert(LIR_OpConvert* op); void emit_alloc_obj(LIR_OpAllocObj* op); void emit_alloc_array(LIR_OpAllocArray* op); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIR.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIR.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIR.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIR.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1012,15 +1012,6 @@ do_temp(opProfileType->_tmp); break; } -#if INCLUDE_ALL_GCS - case lir_shenandoah_wb: { - assert(op->as_OpShenandoahWriteBarrier() != NULL, "must be"); - LIR_OpShenandoahWriteBarrier* opShenandoahWB = (LIR_OpShenandoahWriteBarrier*) op; - do_input(opShenandoahWB->_opr); - do_output(opShenandoahWB->_result); - break; - } -#endif default: ShouldNotReachHere(); } @@ -1119,12 +1110,6 @@ } } -#if INCLUDE_ALL_GCS -void LIR_OpShenandoahWriteBarrier::emit_code(LIR_Assembler* masm) { - masm->emit_opShenandoahWriteBarrier(this); -} -#endif - void LIR_OpConvert::emit_code(LIR_Assembler* masm) { masm->emit_opConvert(this); if (stub() != NULL) { @@ -1851,9 +1836,6 @@ case lir_profile_call: s = "profile_call"; break; // LIR_OpProfileType case lir_profile_type: s = "profile_type"; break; -#if INCLUDE_ALL_GCS - case lir_shenandoah_wb: s = "shenandoah_wb"; break; -#endif // LIR_OpAssert #ifdef ASSERT case lir_assert: s = "assert"; break; @@ -1864,13 +1846,6 @@ return s; } -#if INCLUDE_ALL_GCS -void LIR_OpShenandoahWriteBarrier::print_instr(outputStream* out) const { - out->print("[obj: "); in_opr()->print(out); out->print("]"); - out->print("[res: "); result_opr()->print(out); out->print("]"); -} -#endif - // LIR_OpJavaCall void LIR_OpJavaCall::print_instr(outputStream* out) const { out->print("call: "); @@ -2147,11 +2122,13 @@ // LIR_OpProfileType void LIR_OpProfileType::print_instr(outputStream* out) const { out->print("exact = "); - if (exact_klass()) + if (exact_klass() == NULL) { + out->print("unknown"); + } else { exact_klass()->print_name_on(out); - else - out->print("(null)"); + } out->print(" current = "); ciTypeEntries::print_ciklass(out, current_klass()); + out->print(" "); mdp()->print(out); out->print(" "); obj()->print(out); out->print(" "); tmp()->print(out); out->print(" "); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -33,7 +33,8 @@ #include "ci/ciArrayKlass.hpp" #include "ci/ciInstance.hpp" #include "ci/ciObjArray.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/bitMap.inline.hpp" @@ -245,22 +246,14 @@ void LIRItem::load_item_force(LIR_Opr reg) { LIR_Opr r = result(); if (r != reg) { - _result = _gen->force_opr_to(r, reg); - } -} - -LIR_Opr LIRGenerator::force_opr_to(LIR_Opr op, LIR_Opr reg) { - if (op != reg) { #if !defined(ARM) && !defined(E500V2) - if (op->type() != reg->type()) { + if (r->type() != reg->type()) { // moves between different types need an intervening spill slot - op = force_to_spill(op, reg->type()); + r = _gen->force_to_spill(r, reg->type()); } #endif - __ move(op, reg); - return reg; - } else { - return op; + __ move(r, reg); + _result = reg; } } @@ -1238,6 +1231,14 @@ LIR_Opr result = rlock_result(x); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + LIR_Opr tmp = new_register(T_OBJECT); + __ load(referent_field_adr, tmp, info); + tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, NULL, true); + __ move(tmp, result); + } else +#endif __ load(referent_field_adr, result, info); // Register the value in the referent field with the pre-barrier @@ -1429,9 +1430,13 @@ #if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: - case BarrierSet::ShenandoahBarrierSet: G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info); break; + case BarrierSet::ShenandoahBarrierSet: + if (ShenandoahSATBBarrier) { + G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info); + } + break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: @@ -1455,6 +1460,7 @@ G1SATBCardTableModRef_post_barrier(addr, new_val); break; case BarrierSet::ShenandoahBarrierSet: + ShenandoahBarrierSetC1::bsc1()->storeval_barrier(this, new_val, NULL, false); break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: @@ -1619,6 +1625,11 @@ } else { __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp); } + + if (UseConcMarkSweepGC && CMSPrecleaningEnabled) { + __ membar_storestore(); + } + if (can_inline_as_constant(card_table_base)) { __ move(LIR_OprFact::intConst(0), new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE)); @@ -1709,25 +1720,14 @@ } #endif - LIR_Opr obj = object.result(); - if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()))) { // Emit an explicit null check because the offset is too large. // If the class is not loaded and the object is NULL, we need to deoptimize to throw a // NoClassDefFoundError in the interpreter instead of an implicit NPE from compiled code. - __ null_check(obj, new CodeEmitInfo(info), /* deoptimize */ needs_patching); - } - - LIR_Opr val = value.result(); - -#if INCLUDE_ALL_GCS - obj = shenandoah_write_barrier(obj, info, x->needs_null_check()); - if (is_oop && UseShenandoahGC) { - val = shenandoah_read_barrier(val, NULL, true); + __ null_check(object.result(), new CodeEmitInfo(info), /* deoptimize */ needs_patching); } -#endif LIR_Address* address; if (needs_patching) { @@ -1735,9 +1735,9 @@ // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. - address = new LIR_Address(obj, PATCHED_ADDR, field_type); + address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { - address = generate_address(obj, x->offset(), field_type); + address = generate_address(object.result(), x->offset(), field_type); } if (is_volatile && os::is_MP()) { @@ -1754,15 +1754,15 @@ } if (is_volatile && !needs_patching) { - volatile_field_store(val, address, info); + volatile_field_store(value.result(), address, info); } else { LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; - __ store(val, address, info, patch_code); + __ store(value.result(), address, info, patch_code); } if (is_oop) { // Store to object so mark the card of the header - post_barrier(obj, val); + post_barrier(object.result(), value.result()); } if (is_volatile && os::is_MP()) { @@ -1800,12 +1800,12 @@ } #endif - LIR_Opr obj = object.result(); bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception(); if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()) || stress_deopt)) { + LIR_Opr obj = object.result(); if (stress_deopt) { obj = new_register(T_OBJECT); __ move(LIR_OprFact::oopConst(NULL), obj); @@ -1816,10 +1816,6 @@ __ null_check(obj, new CodeEmitInfo(info), /* deoptimize */ needs_patching); } -#if INCLUDE_ALL_GCS - obj = shenandoah_read_barrier(obj, info, x->needs_null_check() && x->explicit_null_check() != NULL); -#endif - LIR_Opr reg = rlock_result(x, field_type); LIR_Address* address; if (needs_patching) { @@ -1827,73 +1823,40 @@ // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. - address = new LIR_Address(obj, PATCHED_ADDR, field_type); + address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { - address = generate_address(obj, x->offset(), field_type); + address = generate_address(object.result(), x->offset(), field_type); } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (field_type == T_OBJECT || field_type == T_ARRAY)) { + LIR_Opr tmp = new_register(T_OBJECT); + if (is_volatile && !needs_patching) { + volatile_field_load(address, tmp, info); + } else { + LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; + __ load(address, tmp, info, patch_code); + } + if (is_volatile && os::is_MP()) { + __ membar_acquire(); + } + tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, NULL, true); + __ move(tmp, reg); + } else +#endif + { if (is_volatile && !needs_patching) { volatile_field_load(address, reg, info); } else { LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; __ load(address, reg, info, patch_code); } - if (is_volatile && os::is_MP()) { __ membar_acquire(); } -} - -#if INCLUDE_ALL_GCS -LIR_Opr LIRGenerator::shenandoah_read_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { - if (UseShenandoahGC && ShenandoahReadBarrier) { - - LabelObj* done = new LabelObj(); - LIR_Opr result = new_register(T_OBJECT); - __ move(obj, result); - if (need_null_check) { - __ cmp(lir_cond_equal, result, LIR_OprFact::oopConst(NULL)); - __ branch(lir_cond_equal, T_LONG, done->label()); - } - LIR_Address* brooks_ptr_address = generate_address(result, ShenandoahBrooksPointer::byte_offset(), T_ADDRESS); - __ load(brooks_ptr_address, result, info ? new CodeEmitInfo(info) : NULL, lir_patch_none); - - __ branch_destination(done->label()); - return result; - } else { - return obj; - } -} - -LIR_Opr LIRGenerator::ensure_in_register(LIR_Opr obj) { - if (!obj->is_register()) { - LIR_Opr obj_reg = new_register(T_OBJECT); - if (obj->is_constant()) { - __ move(obj, obj_reg); - } else { - __ leal(obj, obj_reg); - } - obj = obj_reg; } - return obj; } -LIR_Opr LIRGenerator::shenandoah_write_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { - if (UseShenandoahGC && ShenandoahWriteBarrier) { - - LIR_Opr result = new_register(T_OBJECT); - obj = ensure_in_register(obj); - assert(obj->is_register(), "must be a register at this point"); - - __ shenandoah_wb(obj, result, info ? new CodeEmitInfo(info) : NULL, need_null_check); - return result; - - } else { - return obj; - } -} -#endif - //------------------------java.nio.Buffer.checkIndex------------------------ @@ -1912,15 +1875,11 @@ if (GenerateRangeChecks) { CodeEmitInfo* info = state_for(x); CodeStub* stub = new RangeCheckStub(info, index.result(), true); - LIR_Opr buf_obj = buf.result(); -#if INCLUDE_ALL_GCS - buf_obj = shenandoah_read_barrier(buf_obj, info, false); -#endif if (index.result()->is_constant()) { - cmp_mem_int(lir_cond_belowEqual, buf_obj, java_nio_Buffer::limit_offset(), index.result()->as_jint(), info); + cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info); __ branch(lir_cond_belowEqual, T_INT, stub); } else { - cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf_obj, + cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(), java_nio_Buffer::limit_offset(), T_INT, info); __ branch(lir_cond_aboveEqual, T_INT, stub); } @@ -1994,14 +1953,8 @@ } } - LIR_Opr ary = array.result(); - -#if INCLUDE_ALL_GCS - ary = shenandoah_read_barrier(ary, null_check_info, null_check_info != NULL); -#endif - // emit array address setup early so it schedules better - LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), false); + LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false); if (GenerateRangeChecks && needs_range_check) { if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { @@ -2012,13 +1965,24 @@ __ cmp(lir_cond_belowEqual, length.result(), index.result()); __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); } else { - array_range_check(ary, index.result(), null_check_info, range_check_info); + array_range_check(array.result(), index.result(), null_check_info, range_check_info); // The range check performs the null check, so clear it out for the load null_check_info = NULL; } } - __ move(array_addr, rlock_result(x, x->elt_type()), null_check_info); + LIR_Opr result = rlock_result(x, x->elt_type()); + +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (x->elt_type() == T_OBJECT || x->elt_type() == T_ARRAY)) { + LIR_Opr tmp = new_register(T_OBJECT); + __ move(array_addr, tmp, null_check_info); + tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, NULL, true); + __ move(tmp, result); + } else +#endif + __ move(array_addr, result, null_check_info); + } @@ -2307,6 +2271,14 @@ LIR_Opr value = rlock_result(x, x->basic_type()); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (type == T_OBJECT || type == T_ARRAY)) { + LIR_Opr tmp = new_register(T_OBJECT); + get_Object_unsafe(tmp, src.result(), off.result(), type, x->is_volatile()); + tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, NULL, true); + __ move(tmp, value); + } else +#endif get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile()); #if INCLUDE_ALL_GCS @@ -2900,9 +2872,6 @@ __ load_stack_address_monitor(0, lock); CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, x->check_flag(Instruction::DeoptimizeOnException)); -#if INCLUDE_ALL_GCS - obj = shenandoah_write_barrier(obj, info, false); -#endif CodeStub* slow_path = new MonitorEnterStub(obj, lock, info); // receiver is guaranteed non-NULL so don't need CodeEmitInfo diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIRGenerator.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -153,7 +153,7 @@ // only the classes below belong in the same file class LIRGenerator: public InstructionVisitor, public BlockClosure { - + friend class ShenandoahBarrierSetC1; private: Compilation* _compilation; ciMethod* _method; // method that we are compiling @@ -226,8 +226,6 @@ LIR_Opr round_item(LIR_Opr opr); LIR_Opr force_to_spill(LIR_Opr value, BasicType t); - LIR_Opr force_opr_to(LIR_Opr op, LIR_Opr reg); - PhiResolverState& resolver_state() { return _resolver_state; } void move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val); @@ -269,12 +267,6 @@ void pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val, bool do_load, bool patch, CodeEmitInfo* info); void post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); -#if INCLUDE_ALL_GCS - LIR_Opr shenandoah_read_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check); - LIR_Opr shenandoah_write_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check); - LIR_Opr ensure_in_register(LIR_Opr obj); -#endif - // specific implementations // pre barriers diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIR.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIR.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_LIR.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_LIR.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -871,9 +871,6 @@ class LIR_OpConvert; class LIR_OpAllocObj; class LIR_OpRoundFP; -#if INCLUDE_ALL_GCS -class LIR_OpShenandoahWriteBarrier; -#endif class LIR_Op2; class LIR_OpDelay; class LIR_Op3; @@ -940,9 +937,6 @@ , lir_pack64 , lir_unpack64 , lir_unwind -#if INCLUDE_ALL_GCS - , lir_shenandoah_wb -#endif , end_op1 , begin_op2 , lir_cmp @@ -1157,9 +1151,6 @@ virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; } virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; } virtual LIR_OpProfileType* as_OpProfileType() { return NULL; } -#if INCLUDE_ALL_GCS - virtual LIR_OpShenandoahWriteBarrier* as_OpShenandoahWriteBarrier() { return NULL; } -#endif #ifdef ASSERT virtual LIR_OpAssert* as_OpAssert() { return NULL; } #endif @@ -1474,24 +1465,6 @@ virtual void print_instr(outputStream* out) const PRODUCT_RETURN; }; -#if INCLUDE_ALL_GCS -class LIR_OpShenandoahWriteBarrier : public LIR_Op1 { - friend class LIR_OpVisitState; - -private: - bool _need_null_check; - -public: - LIR_OpShenandoahWriteBarrier(LIR_Opr obj, LIR_Opr result, CodeEmitInfo* info, bool need_null_check) : LIR_Op1(lir_shenandoah_wb, obj, result, T_OBJECT, lir_patch_none, info), _need_null_check(need_null_check) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled"); - } - bool need_null_check() const { return _need_null_check; } - virtual void emit_code(LIR_Assembler* masm); - virtual LIR_OpShenandoahWriteBarrier* as_OpShenandoahWriteBarrier() { return this; } - virtual void print_instr(outputStream* out) const PRODUCT_RETURN; - -}; -#endif class ConversionStub; @@ -2180,10 +2153,6 @@ void convert(Bytecodes::Code code, LIR_Opr left, LIR_Opr dst, ConversionStub* stub = NULL/*, bool is_32bit = false*/) { append(new LIR_OpConvert(code, left, dst, stub)); } #endif -#if INCLUDE_ALL_GCS - void shenandoah_wb(LIR_Opr obj, LIR_Opr result, CodeEmitInfo* info, bool need_null_check) { append(new LIR_OpShenandoahWriteBarrier(obj, result, info, need_null_check)); } -#endif - void logical_and (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_and, left, right, dst)); } void logical_or (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_or, left, right, dst)); } void logical_xor (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_xor, left, right, dst)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_Runtime1.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_Runtime1.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/c1/c1_Runtime1.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/c1/c1_Runtime1.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1340,10 +1340,6 @@ if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed; if (length == 0) return ac_ok; - - oopDesc::bs()->read_barrier(src); - oopDesc::bs()->write_barrier(dst); - if (src->is_typeArray()) { Klass* klass_oop = src->klass(); if (klass_oop != dst->klass()) return ac_failed; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciEnv.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciEnv.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciEnv.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciEnv.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -508,7 +508,7 @@ // Calculate accessibility the hard way. if (!k->is_loaded()) { is_accessible = false; - } else if (! oopDesc::equals(k->loader(), accessor->loader()) && + } else if (k->loader() != accessor->loader() && get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) { // Loaded only remotely. Not linked yet. is_accessible = false; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,7 +28,6 @@ #include "ci/ciInstanceKlass.hpp" #include "ci/ciUtilities.hpp" #include "classfile/systemDictionary.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" @@ -179,12 +178,12 @@ // ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) { #ifdef ASSERT - if (!((offset >= 0 && offset < layout_helper()) || (UseShenandoahGC && offset == ShenandoahBrooksPointer::byte_offset()))) { + if (!(offset >= 0 && offset < layout_helper())) { tty->print("*** get_canonical_holder(%d) on ", offset); this->print(); tty->print_cr(" ***"); - fatal("offset must be tame"); - } + }; + assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); #endif if (offset < instanceOopDesc::base_offset_in_bytes()) { @@ -716,27 +715,3 @@ ik->do_local_static_fields(&sffp); } } - -#ifdef ASSERT -bool ciInstanceKlass::debug_final_field_at(int offset) { - GUARDED_VM_ENTRY( - InstanceKlass* ik = get_instanceKlass(); - fieldDescriptor fd; - if (ik->find_field_from_offset(offset, false, &fd)) { - return fd.is_final(); - } - ); - return false; -} - -bool ciInstanceKlass::debug_stable_field_at(int offset) { - GUARDED_VM_ENTRY( - InstanceKlass* ik = get_instanceKlass(); - fieldDescriptor fd; - if (ik->find_field_from_offset(offset, false, &fd)) { - return fd.is_stable(); - } - ); - return false; -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciInstanceKlass.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -257,11 +257,6 @@ // Dump the current state of this klass for compilation replay. virtual void dump_replay_data(outputStream* out); - -#ifdef ASSERT - bool debug_final_field_at(int offset); - bool debug_stable_field_at(int offset); -#endif }; #endif // SHARE_VM_CI_CIINSTANCEKLASS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -250,7 +250,7 @@ // into the cache. Handle keyHandle(key); ciObject* new_object = create_new_object(keyHandle()); - assert(oopDesc::equals(keyHandle(), new_object->get_oop()), "must be properly recorded"); + assert(keyHandle() == new_object->get_oop(), "must be properly recorded"); init_ident_of(new_object); assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be"); @@ -488,8 +488,8 @@ for (int i=0; i<_unloaded_klasses->length(); i++) { ciKlass* entry = _unloaded_klasses->at(i); if (entry->name()->equals(name) && - oopDesc::equals(entry->loader(), loader) && - oopDesc::equals(entry->protection_domain(), domain)) { + entry->loader() == loader && + entry->protection_domain() == domain) { // We've found a match. return entry; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/ci/ciObjectFactory.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -78,7 +78,7 @@ void ensure_metadata_alive(ciMetadata* m); static bool is_equal(NonPermObject* p, oop key) { - return oopDesc::equals(p->object()->get_oop(), key); + return p->object()->get_oop() == key; } NonPermObject* &find_non_perm(oop key); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/classLoaderData.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/classLoaderData.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/classLoaderData.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/classLoaderData.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -218,7 +218,7 @@ oop curr = from; while (curr != NULL) { - if (oopDesc::equals(curr, to)) { + if (curr == to) { return; // this class loader is in the parent list, no need to add it. } curr = java_lang_ClassLoader::parent(curr); @@ -240,7 +240,7 @@ objArrayOop last = NULL; while (ok != NULL) { last = ok; - if (oopDesc::equals(ok->obj_at(0), dependency())) { + if (ok->obj_at(0) == dependency()) { // Don't need to add it return; } @@ -279,7 +279,7 @@ while (end != NULL) { last = end; // check again if another thread added it to the end. - if (oopDesc::equals(end->obj_at(0), loader_or_mirror)) { + if (end->obj_at(0) == loader_or_mirror) { // Don't need to add it return; } @@ -584,7 +584,7 @@ if (!is_anonymous) { - ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(oopDesc::bs()->write_barrier(loader())); + ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader()); // First, Atomically set it ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); if (old != NULL) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/classLoaderStats.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/classLoaderStats.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/classLoaderStats.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/classLoaderStats.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -98,7 +98,7 @@ class ClassLoaderStatsClosure : public CLDClosure { protected: static bool oop_equals(oop const& s1, oop const& s2) { - return oopDesc::equals(s1, s2); + return s1 == s2; } static unsigned oop_hash(oop const& s1) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/dictionary.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/dictionary.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/dictionary.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/dictionary.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -91,13 +91,13 @@ bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { #ifdef ASSERT - if (oopDesc::equals(protection_domain, klass()->protection_domain())) { + if (protection_domain == klass()->protection_domain()) { // Ensure this doesn't show up in the pd_set (invariant) bool in_pd_set = false; for (ProtectionDomainEntry* current = _pd_set; current != NULL; current = current->next()) { - if (oopDesc::equals(current->protection_domain(), protection_domain)) { + if (current->protection_domain() == protection_domain) { in_pd_set = true; break; } @@ -109,7 +109,7 @@ } #endif /* ASSERT */ - if (oopDesc::equals(protection_domain, klass()->protection_domain())) { + if (protection_domain == klass()->protection_domain()) { // Succeeds trivially return true; } @@ -117,7 +117,7 @@ for (ProtectionDomainEntry* current = _pd_set; current != NULL; current = current->next()) { - if (oopDesc::equals(current->protection_domain(), protection_domain)) return true; + if (current->protection_domain() == protection_domain) return true; } return false; } @@ -596,7 +596,7 @@ ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, oop protection_domain) { for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) { - if (oopDesc::equals(e->protection_domain(), protection_domain)) { + if (e->protection_domain() == protection_domain) { return e; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/javaClasses.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/javaClasses.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/javaClasses.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/javaClasses.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -52,6 +52,10 @@ #include "runtime/vframe.hpp" #include "utilities/preserveException.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#endif + PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ @@ -206,8 +210,7 @@ int length = UTF8::unicode_length(utf8_str); Handle h_obj = basic_create(length, CHECK_NH); if (length > 0) { - typeArrayOop buffer = value(h_obj()); - UTF8::convert_to_unicode(utf8_str, buffer->char_at_addr(0), length); + UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length); } return h_obj; } @@ -221,8 +224,7 @@ int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length()); Handle h_obj = basic_create(length, CHECK_NH); if (length > 0) { - typeArrayOop buffer = value(h_obj()); - UTF8::convert_to_unicode((char*)symbol->bytes(), buffer->char_at_addr(0), length); + UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length); } return h_obj; } @@ -628,7 +630,7 @@ } // set the classLoader field in the java_lang_Class instance - assert(oopDesc::equals(class_loader(), k->class_loader()), "should be same"); + assert(class_loader() == k->class_loader(), "should be same"); set_class_loader(mirror(), class_loader()); // Setup indirection from klass->mirror last @@ -653,7 +655,7 @@ } void java_lang_Class::set_oop_size(oop java_class, int size) { assert(_oop_size_offset != 0, "must be set"); - java_class->int_field_put_raw(_oop_size_offset, size); + java_class->int_field_put(_oop_size_offset, size); } int java_lang_Class::static_oop_field_count(oop java_class) { assert(_static_oop_field_count_offset != 0, "must be set"); @@ -839,9 +841,9 @@ // Note: create_basic_type_mirror above initializes ak to a non-null value. type = ArrayKlass::cast(ak)->element_type(); } else { - assert(oopDesc::equals(java_class, Universe::void_mirror()), "only valid non-array primitive"); + assert(java_class == Universe::void_mirror(), "only valid non-array primitive"); } - assert(oopDesc::equals(Universe::java_mirror(type), java_class), "must be consistent"); + assert(Universe::java_mirror(type) == java_class, "must be consistent"); return type; } @@ -1209,11 +1211,18 @@ oop java_lang_Throwable::unassigned_stacktrace() { InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Throwable_klass()); address addr = ik->static_field_addr(static_unassigned_stacktrace_offset); + oop result; if (UseCompressedOops) { - return oopDesc::load_decode_heap_oop((narrowOop *)addr); + result = oopDesc::load_decode_heap_oop((narrowOop *)addr); } else { - return oopDesc::load_decode_heap_oop((oop*)addr); + result = oopDesc::load_decode_heap_oop((oop*)addr); + } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(result); } +#endif + return result; } oop java_lang_Throwable::backtrace(oop throwable) { @@ -2639,11 +2648,18 @@ oop java_lang_ref_Reference::pending_list_lock() { InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass()); address addr = ik->static_field_addr(static_lock_offset); + oop result; if (UseCompressedOops) { - return oopDesc::load_decode_heap_oop((narrowOop *)addr); + result = oopDesc::load_decode_heap_oop((narrowOop *)addr); } else { - return oopDesc::load_decode_heap_oop((oop*)addr); + result = oopDesc::load_decode_heap_oop((oop*)addr); + } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(result); } +#endif + return result; } HeapWord *java_lang_ref_Reference::pending_list_addr() { @@ -2655,11 +2671,18 @@ oop java_lang_ref_Reference::pending_list() { char *addr = (char *)pending_list_addr(); + oop result; if (UseCompressedOops) { - return oopDesc::load_decode_heap_oop((narrowOop *)addr); + result = oopDesc::load_decode_heap_oop((narrowOop *)addr); } else { - return oopDesc::load_decode_heap_oop((oop*)addr); + result = oopDesc::load_decode_heap_oop((oop*)addr); + } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(result); } +#endif + return result; } @@ -2881,12 +2904,12 @@ } bool java_lang_invoke_MemberName::equals(oop mn1, oop mn2) { - if (oopDesc::equals(mn1, mn2)) { + if (mn1 == mn2) { return true; } return (vmtarget(mn1) == vmtarget(mn2) && flags(mn1) == flags(mn2) && vmindex(mn1) == vmindex(mn2) && - oopDesc::equals(clazz(mn1), clazz(mn2))); + clazz(mn1) == clazz(mn2)); } oop java_lang_invoke_LambdaForm::vmentry(oop lform) { @@ -2934,14 +2957,14 @@ } bool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) { - if (oopDesc::equals(mt1, mt2)) + if (mt1 == mt2) return true; - if (! oopDesc::equals(rtype(mt1), rtype(mt2))) + if (rtype(mt1) != rtype(mt2)) return false; if (ptype_count(mt1) != ptype_count(mt2)) return false; for (int i = ptype_count(mt1) - 1; i >= 0; i--) { - if (! oopDesc::equals(ptype(mt1, i), ptype(mt2, i))) + if (ptype(mt1, i) != ptype(mt2, i)) return false; } return true; @@ -3065,7 +3088,6 @@ } ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) { - loader = oopDesc::bs()->read_barrier(loader); return *java_lang_ClassLoader::loader_data_addr(loader); } @@ -3094,7 +3116,7 @@ // This loop taken verbatim from ClassLoader.java: do { acl = parent(acl); - if (oopDesc::equals(cl, acl)) { + if (cl == acl) { return true; } assert(++loop_count > 0, "loop_count overflow"); @@ -3121,7 +3143,7 @@ oop cl = SystemDictionary::java_system_loader(); while(cl != NULL) { - if (oopDesc::equals(cl, loader)) return true; + if (cl == loader) return true; cl = parent(cl); } return false; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/symbolTable.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/symbolTable.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/symbolTable.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/symbolTable.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -721,7 +721,7 @@ // considered dead. The SATB part of G1 needs to get notified about this // potential resurrection, otherwise the marking might not find the object. #if INCLUDE_ALL_GCS - if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && string != NULL) { + if ((UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) && string != NULL) { G1SATBCardTableModRefBS::enqueue(string); } #endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/systemDictionary.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/systemDictionary.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/systemDictionary.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/systemDictionary.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -353,7 +353,7 @@ ((quicksuperk = InstanceKlass::cast(childk)->super()) != NULL) && ((quicksuperk->name() == class_name) && - (oopDesc::equals(quicksuperk->class_loader(), class_loader())))) { + (quicksuperk->class_loader() == class_loader()))) { return quicksuperk; } else { PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data); @@ -494,7 +494,7 @@ bool calledholdinglock = ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject); assert(calledholdinglock,"must hold lock for notify"); - assert((! oopDesc::equals(lockObject(), _system_loader_lock_obj) && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); + assert((lockObject() != _system_loader_lock_obj && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); ObjectSynchronizer::notifyall(lockObject, THREAD); intptr_t recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD); SystemDictionary_lock->wait(); @@ -811,7 +811,7 @@ // If everything was OK (no exceptions, no null return value), and // class_loader is NOT the defining loader, do a little more bookkeeping. if (!HAS_PENDING_EXCEPTION && !k.is_null() && - ! oopDesc::equals(k->class_loader(), class_loader())) { + k->class_loader() != class_loader()) { check_constraints(d_index, d_hash, k, class_loader, false, THREAD); @@ -989,7 +989,7 @@ // Create a new CLD for anonymous class, that uses the same class loader // as the host_klass assert(EnableInvokeDynamic, ""); - guarantee(oopDesc::equals(host_klass->class_loader(), class_loader()), "should be the same"); + guarantee(host_klass->class_loader() == class_loader(), "should be the same"); guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping"); loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL); loader_data->record_dependency(host_klass(), CHECK_NULL); @@ -1576,7 +1576,7 @@ == ObjectSynchronizer::owner_other) { // contention will likely happen, so increment the corresponding // contention counter. - if (oopDesc::equals(loader_lock(), _system_loader_lock_obj)) { + if (loader_lock() == _system_loader_lock_obj) { ClassLoader::sync_systemLoaderLockContentionRate()->inc(); } else { ClassLoader::sync_nonSystemLoaderLockContentionRate()->inc(); @@ -2078,7 +2078,7 @@ // cleared if revocation occurs too often for this type // NOTE that we must only do this when the class is initally // defined, not each time it is referenced from a new class loader - if (oopDesc::equals(k->class_loader(), class_loader())) { + if (k->class_loader() == class_loader()) { k->set_prototype_header(markOopDesc::biased_locking_prototype()); } } @@ -2264,7 +2264,7 @@ Handle loader1, Handle loader2, bool is_method, TRAPS) { // Nothing to do if loaders are the same. - if (oopDesc::equals(loader1(), loader2())) { + if (loader1() == loader2()) { return NULL; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/vmSymbols.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/vmSymbols.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/classfile/vmSymbols.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/classfile/vmSymbols.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -863,6 +863,12 @@ do_name( implCompressMB_name, "implCompressMultiBlock0") \ do_signature(implCompressMB_signature, "([BII)I") \ \ + /* support for com.sun.crypto.provider.GHASH */ \ + do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH") \ + do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \ + do_name(processBlocks_name, "processBlocks") \ + do_signature(ghash_processBlocks_signature, "([BII[J[J)V") \ + \ /* support for java.util.zip */ \ do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \ do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/code/dependencies.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/code/dependencies.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/code/dependencies.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/code/dependencies.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1507,12 +1507,12 @@ assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity"); if (changes == NULL) { // Validate all CallSites - if (! oopDesc::equals(java_lang_invoke_CallSite::target(call_site), method_handle)) + if (java_lang_invoke_CallSite::target(call_site) != method_handle) return call_site->klass(); // assertion failed } else { // Validate the given CallSite - if (oopDesc::equals(call_site, changes->call_site()) && ! oopDesc::equals(java_lang_invoke_CallSite::target(call_site), changes->method_handle())) { - assert(! oopDesc::equals(method_handle, changes->method_handle()), "must be"); + if (call_site == changes->call_site() && java_lang_invoke_CallSite::target(call_site) != changes->method_handle()) { + assert(method_handle != changes->method_handle(), "must be"); return call_site->klass(); // assertion failed } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/compiler/oopMap.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/compiler/oopMap.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/compiler/oopMap.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/compiler/oopMap.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -43,6 +43,7 @@ class frame; class RegisterMap; class DerivedPointerEntry; +class OopClosure; class OopMapValue: public StackObj { friend class VMStructs; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -161,6 +161,8 @@ } _dictionary->set_par_lock(&_parDictionaryAllocLock); } + + _used_stable = 0; } // Like CompactibleSpace forward() but always calls cross_threshold() to @@ -377,6 +379,14 @@ return capacity() - free(); } +size_t CompactibleFreeListSpace::used_stable() const { + return _used_stable; +} + +void CompactibleFreeListSpace::recalculate_used_stable() { + _used_stable = used(); +} + size_t CompactibleFreeListSpace::free() const { // "MT-safe, but not MT-precise"(TM), if you will: i.e. // if you do this while the structures are in flux you @@ -1218,6 +1228,13 @@ debug_only(fc->mangleAllocated(size)); } + // During GC we do not need to recalculate the stable used value for + // every allocation in old gen. It is done once at the end of GC instead + // for performance reasons. + if (!Universe::heap()->is_gc_active()) { + recalculate_used_stable(); + } + return res; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -148,6 +148,9 @@ // Used to keep track of limit of sweep for the space HeapWord* _sweep_limit; + // Stable value of used(). + size_t _used_stable; + // Support for compacting cms HeapWord* cross_threshold(HeapWord* start, HeapWord* end); HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); @@ -343,6 +346,17 @@ // which overestimates the region by returning the entire // committed region (this is safe, but inefficient). + // Returns monotonically increasing stable used space bytes for CMS. + // This is required for jstat and other memory monitoring tools + // that might otherwise see inconsistent used space values during a garbage + // collection, promotion or allocation into compactibleFreeListSpace. + // The value returned by this function might be smaller than the + // actual value. + size_t used_stable() const; + // Recalculate and cache the current stable used() value. Only to be called + // in places where we can be sure that the result is stable. + void recalculate_used_stable(); + // Returns a subregion of the space containing all the objects in // the space. MemRegion used_region() const { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -869,6 +869,10 @@ return _cmsSpace->max_alloc_in_words() * HeapWordSize; } +size_t ConcurrentMarkSweepGeneration::used_stable() const { + return cmsSpace()->used_stable(); +} + size_t ConcurrentMarkSweepGeneration::max_available() const { return free() + _virtual_space.uncommitted_size(); } @@ -1955,6 +1959,8 @@ FreelistLocker z(this); MetaspaceGC::compute_new_size(); _cmsGen->compute_new_size_free_list(); + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); } // A work method used by foreground collection to determine @@ -2768,6 +2774,7 @@ _capacity_at_prologue = capacity(); _used_at_prologue = used(); + _cmsSpace->recalculate_used_stable(); // Delegate to CMScollector which knows how to coordinate between // this and any other CMS generations that it is responsible for @@ -2837,6 +2844,7 @@ _eden_chunk_index = 0; size_t cms_used = _cmsGen->cmsSpace()->used(); + _cmsGen->cmsSpace()->recalculate_used_stable(); // update performance counters - this uses a special version of // update_counters() that allows the utilization to be passed as a @@ -3672,6 +3680,7 @@ _collectorState = Marking; } SpecializationStats::print(); + _cmsGen->cmsSpace()->recalculate_used_stable(); } void CMSCollector::checkpointRootsInitialWork(bool asynch) { @@ -5066,10 +5075,12 @@ Mutex::_no_safepoint_check_flag); assert(!init_mark_was_synchronous, "but that's impossible!"); checkpointRootsFinalWork(asynch, clear_all_soft_refs, false); + _cmsGen->cmsSpace()->recalculate_used_stable(); } else { // already have all the locks checkpointRootsFinalWork(asynch, clear_all_soft_refs, init_mark_was_synchronous); + _cmsGen->cmsSpace()->recalculate_used_stable(); } verify_work_stacks_empty(); verify_overflow_empty(); @@ -6368,6 +6379,10 @@ // Update heap occupancy information which is used as // input to soft ref clearing policy at the next gc. Universe::update_heap_info_at_gc(); + + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); + _collectorState = Resizing; } } else { @@ -6467,6 +6482,7 @@ // Gather statistics on the young generation collection. collector()->stats().record_gc0_end(used()); } + _cmsSpace->recalculate_used_stable(); } CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1190,6 +1190,7 @@ double occupancy() const { return ((double)used())/((double)capacity()); } size_t contiguous_available() const; size_t unsafe_max_alloc_nogc() const; + size_t used_stable() const; // over-rides MemRegion used_region() const; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -2520,6 +2520,12 @@ } } } + } else if (GC_locker::should_discard(cause, gc_count_before)) { + // Return to be consistent with VMOp failure due to another + // collection slipping in after our gc_count but before our + // request is processed. _gc_locker collections upgraded by + // GCLockerInvokesConcurrent are handled above and never discarded. + return; } else { if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -376,7 +376,7 @@ MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes), 1U); _sizer_kind = SizerMaxAndNewSize; - _adaptive_size = _min_desired_young_length == _max_desired_young_length; + _adaptive_size = _min_desired_young_length != _max_desired_young_length; } else { _sizer_kind = SizerNewSizeOnly; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -133,7 +133,11 @@ SizerKind _sizer_kind; uint _min_desired_young_length; uint _max_desired_young_length; + + // False when using a fixed young generation size due to command-line options, + // true otherwise. bool _adaptive_size; + uint calculate_default_min_length(uint new_number_of_heap_regions); uint calculate_default_max_length(uint new_number_of_heap_regions); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -530,6 +530,10 @@ full_gc_count = Universe::heap()->total_full_collections(); } + if (GC_locker::should_discard(cause, gc_count)) { + return; + } + VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); VMThread::execute(&op); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -52,11 +52,16 @@ } } +static bool is_cause_full(GCCause::Cause cause) { + return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc) + DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot)); +} + // Only used for System.gc() calls VM_ParallelGCSystemGC::VM_ParallelGCSystemGC(uint gc_count, uint full_gc_count, GCCause::Cause gc_cause) : - VM_GC_Operation(gc_count, gc_cause, full_gc_count, true /* full */) + VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause)) { } @@ -68,8 +73,7 @@ "must be a ParallelScavengeHeap"); GCCauseSetter gccs(heap, _gc_cause); - if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc - DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) { + if (!_full) { // If (and only if) the scavenge fails, this will invoke a full gc. heap->invoke_scavenge(); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -63,7 +63,7 @@ } inline void update_used() { - _used->set_value(_gen->used()); + _used->set_value(_gen->used_stable()); } // special version of update_used() to allow the used value to be @@ -107,7 +107,7 @@ GenerationUsedHelper(Generation* g) : _gen(g) { } inline jlong take_sample() { - return _gen->used(); + return _gen->used_stable(); } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -201,6 +201,19 @@ } } +static bool is_full_gc(int max_level) { + // Return true if max_level is all generations + return (max_level == (GenCollectedHeap::heap()->n_gens() - 1)); +} + +VM_GenCollectFull::VM_GenCollectFull(uint gc_count_before, + uint full_gc_count_before, + GCCause::Cause gc_cause, + int max_level) : + VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, + is_full_gc(max_level) /* full */), + _max_level(max_level) { } + void VM_GenCollectFull::doit() { SvcGCMarker sgcm(SvcGCMarker::FULL); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -201,9 +201,7 @@ VM_GenCollectFull(uint gc_count_before, uint full_gc_count_before, GCCause::Cause gc_cause, - int max_level) - : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */), - _max_level(max_level) { } + int max_level); ~VM_GenCollectFull() {} virtual VMOp_Type type() const { return VMOp_GenCollectFull; } virtual void doit(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,19 +34,7 @@ ShenandoahHeuristics(), _cycle_gap_history(new TruncatedSeq(5)), _conc_mark_duration_history(new TruncatedSeq(5)), - _conc_uprefs_duration_history(new TruncatedSeq(5)) { - - SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); - SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); - - // Final configuration checks - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahReadBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahWriteBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahAcmpBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); -} + _conc_uprefs_duration_history(new TruncatedSeq(5)) {} ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {} @@ -77,9 +65,12 @@ size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0; size_t max_cset = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste); - log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: " - SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M", - free_target / M, actual_free / M, max_cset / M, min_garbage / M); + log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: " + SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s", + byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target), + byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), + byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset), + byte_size_in_proper_unit(min_garbage), proper_unit_for_byte_size(min_garbage)); // Better select garbage-first regions QuickSort::sort(data, (int)size, compare_by_garbage, false); @@ -121,7 +112,7 @@ } // Else ignore } -bool ShenandoahAdaptiveHeuristics::should_start_normal_gc() const { +bool ShenandoahAdaptiveHeuristics::should_start_gc() const { ShenandoahHeap* heap = ShenandoahHeap::heap(); size_t capacity = heap->max_capacity(); size_t available = heap->free_set()->available(); @@ -130,8 +121,9 @@ // anything else. size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold; if (available < min_threshold) { - log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)", - available / M, min_threshold / M); + log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); return true; } @@ -140,8 +132,10 @@ if (_gc_times_learned < max_learn) { size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold; if (available < init_threshold) { - log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)", - _gc_times_learned + 1, max_learn, available / M, init_threshold / M); + log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)", + _gc_times_learned + 1, max_learn, + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold)); return true; } } @@ -165,14 +159,19 @@ double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last; if (average_gc > allocation_headroom / allocation_rate) { - log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.2f MB/s) to deplete free headroom (" SIZE_FORMAT "M)", - average_gc * 1000, allocation_rate / M, allocation_headroom / M); - log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "M (free) - " SIZE_FORMAT "M (spike) - " SIZE_FORMAT "M (penalties) = " SIZE_FORMAT "M", - available / M, spike_headroom / M, penalties / M, allocation_headroom / M); + log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s)", + average_gc * 1000, + byte_size_in_proper_unit(allocation_rate), proper_unit_for_byte_size(allocation_rate), + byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom)); + log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(spike_headroom), proper_unit_for_byte_size(spike_headroom), + byte_size_in_proper_unit(penalties), proper_unit_for_byte_size(penalties), + byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom)); return true; } - return ShenandoahHeuristics::should_start_normal_gc(); + return ShenandoahHeuristics::should_start_gc(); } bool ShenandoahAdaptiveHeuristics::should_start_update_refs() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -47,7 +47,7 @@ virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs); - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual bool should_start_update_refs(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -46,11 +46,10 @@ } // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahReadBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahWriteBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahAcmpBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } @@ -65,7 +64,7 @@ } } -bool ShenandoahAggressiveHeuristics::should_start_normal_gc() const { +bool ShenandoahAggressiveHeuristics::should_start_gc() const { log_info(gc)("Trigger: Start next cycle immediately"); return true; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,7 +34,7 @@ RegionData* data, size_t size, size_t free); - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual bool should_process_references(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -41,15 +41,14 @@ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahGarbageThreshold, 10); // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahReadBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahWriteBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahAcmpBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } -bool ShenandoahCompactHeuristics::should_start_normal_gc() const { +bool ShenandoahCompactHeuristics::should_start_gc() const { ShenandoahHeap* heap = ShenandoahHeap::heap(); size_t capacity = heap->max_capacity(); @@ -59,25 +58,28 @@ size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold; if (available < min_threshold) { - log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)", - available / M, min_threshold / M); + log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); return true; } if (available < threshold_bytes_allocated) { - log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is lower than allocated recently (" SIZE_FORMAT "M)", - available / M, threshold_bytes_allocated / M); + log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is lower than allocated recently (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(threshold_bytes_allocated), proper_unit_for_byte_size(threshold_bytes_allocated)); return true; } size_t bytes_allocated = heap->bytes_allocated_since_gc_start(); if (bytes_allocated > threshold_bytes_allocated) { - log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "M) is larger than allocation threshold (" SIZE_FORMAT "M)", - bytes_allocated / M, threshold_bytes_allocated / M); + log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "%s) is larger than allocation threshold (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated), + byte_size_in_proper_unit(threshold_bytes_allocated), proper_unit_for_byte_size(threshold_bytes_allocated)); return true; } - return ShenandoahHeuristics::should_start_normal_gc(); + return ShenandoahHeuristics::should_start_gc(); } void ShenandoahCompactHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, @@ -86,8 +88,9 @@ // Do not select too large CSet that would overflow the available free space size_t max_cset = actual_free * 3 / 4; - log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M", - actual_free / M, max_cset / M); + log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s", + byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), + byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset)); size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -30,7 +30,7 @@ public: ShenandoahCompactHeuristics(); - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, RegionData* data, size_t size, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,32 +28,7 @@ #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahLogging.hpp" -ShenandoahPassiveHeuristics::ShenandoahPassiveHeuristics() : ShenandoahHeuristics() { - // Do not allow concurrent cycles. - FLAG_SET_DEFAULT(ExplicitGCInvokesConcurrent, false); - FLAG_SET_DEFAULT(ShenandoahImplicitGCInvokesConcurrent, false); - - // Passive runs with max speed, reacts on allocation failure. - FLAG_SET_DEFAULT(ShenandoahPacing, false); - - // No need for evacuation reserve with Full GC, only for Degenerated GC. - if (!ShenandoahDegeneratedGC) { - SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahEvacReserve, 0); - } - - // Disable known barriers by default. - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahWriteBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahReadBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahAcmpBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier); - - // Final configuration checks - // No barriers are required to run. -} - -bool ShenandoahPassiveHeuristics::should_start_normal_gc() const { +bool ShenandoahPassiveHeuristics::should_start_gc() const { // Never do concurrent GCs. return false; } @@ -84,8 +59,9 @@ size_t available = MAX2(capacity / 100 * ShenandoahEvacReserve, actual_free); size_t max_cset = (size_t)(available / ShenandoahEvacWaste); - log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M", - actual_free / M, max_cset / M); + log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s", + byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), + byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset)); size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,9 +28,7 @@ class ShenandoahPassiveHeuristics : public ShenandoahHeuristics { public: - ShenandoahPassiveHeuristics(); - - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual bool should_process_references(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -39,17 +39,16 @@ SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahReadBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahWriteBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahAcmpBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } ShenandoahStaticHeuristics::~ShenandoahStaticHeuristics() {} -bool ShenandoahStaticHeuristics::should_start_normal_gc() const { +bool ShenandoahStaticHeuristics::should_start_gc() const { ShenandoahHeap* heap = ShenandoahHeap::heap(); size_t capacity = heap->max_capacity(); @@ -57,11 +56,12 @@ size_t threshold_available = capacity / 100 * ShenandoahFreeThreshold; if (available < threshold_available) { - log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below free threshold (" SIZE_FORMAT "M)", - available / M, threshold_available / M); + log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below free threshold (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(threshold_available), proper_unit_for_byte_size(threshold_available)); return true; } - return ShenandoahHeuristics::should_start_normal_gc(); + return ShenandoahHeuristics::should_start_gc(); } void ShenandoahStaticHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,7 +32,7 @@ virtual ~ShenandoahStaticHeuristics(); - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, RegionData* data, size_t size, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" +#include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" +#include "utilities/quickSort.hpp" + +ShenandoahTraversalAggressiveHeuristics::ShenandoahTraversalAggressiveHeuristics() : ShenandoahHeuristics(), + _last_cset_select(0) { + // Do not shortcut evacuation + SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100); + + // Aggressive runs with max speed for allocation, to capture races against mutator + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing); + + // Aggressive evacuates everything, so it needs as much evac space as it can get + SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow); + + // If class unloading is globally enabled, aggressive does unloading even with + // concurrent cycles. + if (ClassUnloading) { + SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1); + } + +} + +bool ShenandoahTraversalAggressiveHeuristics::is_experimental() { + return false; +} + +bool ShenandoahTraversalAggressiveHeuristics::is_diagnostic() { + return true; +} + +const char* ShenandoahTraversalAggressiveHeuristics::name() { + return "traversal-aggressive"; +} + +void ShenandoahTraversalAggressiveHeuristics::choose_collection_set(ShenandoahCollectionSet* collection_set) { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + + ShenandoahTraversalGC* traversal_gc = heap->traversal_gc(); + + ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set(); + traversal_set->clear(); + + RegionData *data = get_region_data_cache(heap->num_regions()); + size_t cnt = 0; + + // Step 0. Prepare all regions + for (size_t i = 0; i < heap->num_regions(); i++) { + ShenandoahHeapRegion* r = heap->get_region(i); + if (r->used() > 0) { + if (r->is_regular()) { + data[cnt]._region = r; + data[cnt]._garbage = r->garbage(); + data[cnt]._seqnum_last_alloc = r->seqnum_last_alloc_mutator(); + cnt++; + } + traversal_set->add_region(r); + } + } + + for (size_t i = 0; i < cnt; i++) { + if (data[i]._seqnum_last_alloc > _last_cset_select) continue; + + ShenandoahHeapRegion* r = data[i]._region; + assert (r->is_regular(), "should have been filtered before"); + + if (r->garbage() > 0) { + assert(!collection_set->is_in(r), "must not yet be in cset"); + collection_set->add_region(r); + } + } + + // Clear liveness data + // TODO: Merge it with step 0, but save live data in RegionData before. + for (size_t i = 0; i < heap->num_regions(); i++) { + ShenandoahHeapRegion* r = heap->get_region(i); + if (r->used() > 0) { + r->clear_live_data(); + } + } + + collection_set->update_region_status(); + + _last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc(); +} + +void ShenandoahTraversalAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, + RegionData* data, size_t data_size, + size_t free) { + ShouldNotReachHere(); +} + +bool ShenandoahTraversalAggressiveHeuristics::should_start_gc() const { + log_info(gc)("Trigger: Start next cycle immediately"); + return true; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP +#define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP + +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" + +class ShenandoahTraversalAggressiveHeuristics : public ShenandoahHeuristics { +private: + uint64_t _last_cset_select; + +protected: + virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, + RegionData* data, size_t data_size, + size_t free); + +public: + ShenandoahTraversalAggressiveHeuristics(); + + virtual bool is_experimental(); + + virtual bool is_diagnostic(); + + virtual const char* name(); + + virtual void choose_collection_set(ShenandoahCollectionSet* collection_set); + virtual bool should_start_gc() const; +}; + +#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" +#include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" +#include "utilities/quickSort.hpp" + +ShenandoahTraversalHeuristics::ShenandoahTraversalHeuristics() : ShenandoahHeuristics(), + _last_cset_select(0) {} + +bool ShenandoahTraversalHeuristics::is_experimental() { + return false; +} + +bool ShenandoahTraversalHeuristics::is_diagnostic() { + return false; +} + +const char* ShenandoahTraversalHeuristics::name() { + return "traversal"; +} + +void ShenandoahTraversalHeuristics::choose_collection_set(ShenandoahCollectionSet* collection_set) { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + + ShenandoahTraversalGC* traversal_gc = heap->traversal_gc(); + + ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set(); + traversal_set->clear(); + + RegionData *data = get_region_data_cache(heap->num_regions()); + size_t cnt = 0; + + // Step 0. Prepare all regions + + for (size_t i = 0; i < heap->num_regions(); i++) { + ShenandoahHeapRegion* r = heap->get_region(i); + if (r->used() > 0) { + if (r->is_regular()) { + data[cnt]._region = r; + data[cnt]._garbage = r->garbage(); + data[cnt]._seqnum_last_alloc = r->seqnum_last_alloc_mutator(); + cnt++; + } + traversal_set->add_region(r); + } + } + + // The logic for cset selection is similar to that of adaptive: + // + // 1. We cannot get cset larger than available free space. Otherwise we guarantee OOME + // during evacuation, and thus guarantee full GC. In practice, we also want to let + // application to allocate something. This is why we limit CSet to some fraction of + // available space. In non-overloaded heap, max_cset would contain all plausible candidates + // over garbage threshold. + // + // 2. We should not get cset too low so that free threshold would not be met right + // after the cycle. Otherwise we get back-to-back cycles for no reason if heap is + // too fragmented. In non-overloaded non-fragmented heap min_garbage would be around zero. + // + // Therefore, we start by sorting the regions by garbage. Then we unconditionally add the best candidates + // before we meet min_garbage. Then we add all candidates that fit with a garbage threshold before + // we hit max_cset. When max_cset is hit, we terminate the cset selection. Note that in this scheme, + // ShenandoahGarbageThreshold is the soft threshold which would be ignored until min_garbage is hit. + // + // The significant complication is that liveness data was collected at the previous cycle, and only + // for those regions that were allocated before previous cycle started. + + size_t capacity = heap->max_capacity(); + size_t actual_free = heap->free_set()->available(); + size_t free_target = capacity / 100 * ShenandoahMinFreeThreshold; + size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0; + size_t max_cset = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste); + + log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: " + SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s", + byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target), + byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), + byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset), + byte_size_in_proper_unit(min_garbage), proper_unit_for_byte_size(min_garbage)); + + // Better select garbage-first regions, and then older ones + QuickSort::sort(data, (int) cnt, compare_by_garbage_then_alloc_seq_ascending, false); + + size_t cur_cset = 0; + size_t cur_garbage = 0; + + size_t garbage_threshold = ShenandoahHeapRegion::region_size_bytes() / 100 * ShenandoahGarbageThreshold; + + // Step 1. Add trustworthy regions to collection set. + // + // We can trust live/garbage data from regions that were fully traversed during + // previous cycle. Even if actual liveness is different now, we can only have _less_ + // live objects, because dead objects are not resurrected. Which means we can undershoot + // the collection set, but not overshoot it. + + for (size_t i = 0; i < cnt; i++) { + if (data[i]._seqnum_last_alloc > _last_cset_select) continue; + + ShenandoahHeapRegion* r = data[i]._region; + assert (r->is_regular(), "should have been filtered before"); + + size_t new_garbage = cur_garbage + r->garbage(); + size_t new_cset = cur_cset + r->get_live_data_bytes(); + + if (new_cset > max_cset) { + break; + } + + if ((new_garbage < min_garbage) || (r->garbage() > garbage_threshold)) { + assert(!collection_set->is_in(r), "must not yet be in cset"); + collection_set->add_region(r); + cur_cset = new_cset; + cur_garbage = new_garbage; + } + } + + // Step 2. Try to catch some recently allocated regions for evacuation ride. + // + // Pessimistically assume we are going to evacuate the entire region. While this + // is very pessimistic and in most cases undershoots the collection set when regions + // are mostly dead, it also provides more safety against running into allocation + // failure when newly allocated regions are fully live. + + for (size_t i = 0; i < cnt; i++) { + if (data[i]._seqnum_last_alloc <= _last_cset_select) continue; + + ShenandoahHeapRegion* r = data[i]._region; + assert (r->is_regular(), "should have been filtered before"); + + // size_t new_garbage = cur_garbage + 0; (implied) + size_t new_cset = cur_cset + r->used(); + + if (new_cset > max_cset) { + break; + } + + assert(!collection_set->is_in(r), "must not yet be in cset"); + collection_set->add_region(r); + cur_cset = new_cset; + } + + // Step 3. Clear liveness data + // TODO: Merge it with step 0, but save live data in RegionData before. + for (size_t i = 0; i < heap->num_regions(); i++) { + ShenandoahHeapRegion* r = heap->get_region(i); + if (r->used() > 0) { + r->clear_live_data(); + } + } + + collection_set->update_region_status(); + + _last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc(); +} + +bool ShenandoahTraversalHeuristics::should_start_gc() const { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + assert(!heap->has_forwarded_objects(), "no forwarded objects here"); + + size_t capacity = heap->max_capacity(); + size_t available = heap->free_set()->available(); + + // Check if we are falling below the worst limit, time to trigger the GC, regardless of + // anything else. + size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold; + if (available < min_threshold) { + log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); + return true; + } + + // Check if are need to learn a bit about the application + const size_t max_learn = ShenandoahLearningSteps; + if (_gc_times_learned < max_learn) { + size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold; + if (available < init_threshold) { + log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)", + _gc_times_learned + 1, max_learn, + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold)); + return true; + } + } + + // Check if allocation headroom is still okay. This also factors in: + // 1. Some space to absorb allocation spikes + // 2. Accumulated penalties from Degenerated and Full GC + + size_t allocation_headroom = available; + + size_t spike_headroom = capacity / 100 * ShenandoahAllocSpikeFactor; + size_t penalties = capacity / 100 * _gc_time_penalties; + + allocation_headroom -= MIN2(allocation_headroom, spike_headroom); + allocation_headroom -= MIN2(allocation_headroom, penalties); + + double average_gc = _gc_time_history->avg(); + double time_since_last = time_since_last_gc(); + double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last; + + if (average_gc > allocation_headroom / allocation_rate) { + log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s)", + average_gc * 1000, + byte_size_in_proper_unit(allocation_rate), proper_unit_for_byte_size(allocation_rate), + byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom)); + log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s", + byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), + byte_size_in_proper_unit(spike_headroom), proper_unit_for_byte_size(spike_headroom), + byte_size_in_proper_unit(penalties), proper_unit_for_byte_size(penalties), + byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom)); + return true; + } else if (ShenandoahHeuristics::should_start_gc()) { + return true; + } + + return false; +} + +void ShenandoahTraversalHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, + RegionData* data, size_t data_size, + size_t free) { + ShouldNotReachHere(); +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALHEURISTICS_HPP +#define SHARE_VM_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALHEURISTICS_HPP + +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" + +class ShenandoahTraversalHeuristics : public ShenandoahHeuristics { +private: + uint64_t _last_cset_select; + +protected: + virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, + RegionData* data, size_t data_size, + size_t free); + +public: + ShenandoahTraversalHeuristics(); + + virtual bool is_experimental(); + + virtual bool is_diagnostic(); + + virtual const char* name(); + + virtual void choose_collection_set(ShenandoahCollectionSet* collection_set); + + virtual bool should_start_gc() const; +}; + +#endif // SHARE_VM_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALHEURISTICS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_implementation/shenandoah/preservedMarks.inline.hpp" +#include "utilities/workgroup.hpp" +#include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" +#include "oops/oop.inline.hpp" +#include "utilities/macros.hpp" + +void PreservedMarks::restore() { + while (!_stack.is_empty()) { + const OopAndMarkOop elem = _stack.pop(); + elem.set_mark(); + } + assert_empty(); +} + +void PreservedMarks::adjust_during_full_gc() { + StackIterator iter(_stack); + while (!iter.is_empty()) { + OopAndMarkOop* elem = iter.next_addr(); + + oop obj = elem->get_oop(); + if (obj->is_forwarded()) { + elem->set_oop(obj->forwardee()); + } + } +} + +void PreservedMarks::restore_and_increment(volatile size_t* const total_size_addr) { + const size_t stack_size = size(); + restore(); + // Only do the atomic add if the size is > 0. + if (stack_size > 0) { + Atomic::add(stack_size, (volatile jlong*)total_size_addr); + } +} + +#ifndef PRODUCT +void PreservedMarks::assert_empty() { + assert(_stack.is_empty(), err_msg("stack expected to be empty, size = " SIZE_FORMAT, + _stack.size())); + assert(_stack.cache_size() == 0, + err_msg("stack expected to have no cached segments, cache size = " SIZE_FORMAT, + _stack.cache_size())); +} +#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 == NULL && _num == 0, "do not re-initialize"); + assert(num > 0, "pre-condition"); + if (_in_c_heap) { + _stacks = NEW_C_HEAP_ARRAY(Padded, num, mtGC); + } else { + _stacks = NEW_RESOURCE_ARRAY(Padded, num); + } + for (uint i = 0; i < num; i += 1) { + ::new (_stacks + i) PreservedMarks(); + } + _num = num; + + assert_empty(); +} + +class ParRestoreTask : public AbstractGangTask { +private: + PreservedMarksSet* const _preserved_marks_set; + SequentialSubTasksDone _sub_tasks; + volatile size_t* const _total_size_addr; + +public: + virtual void work(uint worker_id) { + uint task_id = 0; + while (!_sub_tasks.is_task_claimed(/* reference */ task_id)) { + _preserved_marks_set->get(task_id)->restore_and_increment(_total_size_addr); + } + _sub_tasks.all_tasks_completed(); + } + + ParRestoreTask(uint worker_num, + PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) + : AbstractGangTask("Parallel Preserved Mark Restoration"), + _preserved_marks_set(preserved_marks_set), + _total_size_addr(total_size_addr) { + _sub_tasks.set_n_threads(worker_num); + _sub_tasks.set_n_tasks(preserved_marks_set->num()); + } +}; + +void PreservedMarksSet::reclaim() { + assert_empty(); + + for (uint i = 0; i < _num; i += 1) { + _stacks[i].~Padded(); + } + + if (_in_c_heap) { + FREE_C_HEAP_ARRAY(Padded, _stacks, mtGC); + } else { + // the array was resource-allocated, so nothing to do + } + _stacks = NULL; + _num = 0; +} + +#ifndef PRODUCT +void PreservedMarksSet::assert_empty() { + assert(_stacks != NULL && _num > 0, "should have been initialized"); + for (uint i = 0; i < _num; i += 1) { + get(i)->assert_empty(); + } +} +#endif // ndef PRODUCT + +void SharedRestorePreservedMarksTaskExecutor::restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) { + if (_workers == NULL) { + for (uint i = 0; i < preserved_marks_set->num(); i += 1) { + *total_size_addr += preserved_marks_set->get(i)->size(); + preserved_marks_set->get(i)->restore(); + } + } else { + ParRestoreTask task(_workers->active_workers(), preserved_marks_set, total_size_addr); + _workers->run_task(&task); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_VM_GC_SHARED_PRESERVEDMARKS_HPP +#define SHARE_VM_GC_SHARED_PRESERVEDMARKS_HPP + +#include "memory/allocation.hpp" +#include "memory/padded.hpp" +#include "oops/oop.hpp" +#include "utilities/stack.hpp" + +class PreservedMarksSet; +class WorkGang; + +class PreservedMarks { +private: + class OopAndMarkOop { + private: + oop _o; + markOop _m; + + public: + OopAndMarkOop(oop obj, markOop m) : _o(obj), _m(m) { } + + oop get_oop() { return _o; } + inline void set_mark() const; + void set_oop(oop obj) { _o = obj; } + }; + typedef Stack OopAndMarkOopStack; + + OopAndMarkOopStack _stack; + + inline bool should_preserve_mark(oop obj, markOop m) const; + +public: + size_t size() const { return _stack.size(); } + inline void push(oop obj, markOop m); + inline void push_if_necessary(oop obj, markOop m); + // Iterate over the stack, restore all preserved marks, and + // reclaim the memory taken up by the stack segments. + void restore(); + // Iterate over the stack, adjust all preserved marks according + // to their forwarding location stored in the mark. + void adjust_during_full_gc(); + + void restore_and_increment(volatile size_t* const _total_size_addr); + inline static void init_forwarded_mark(oop obj); + + // Assert the stack is empty and has no cached segments. + void assert_empty() PRODUCT_RETURN; + + inline PreservedMarks(); + ~PreservedMarks() { assert_empty(); } +}; + +class RemoveForwardedPointerClosure: public ObjectClosure { +public: + virtual void do_object(oop obj); +}; + +class RestorePreservedMarksTaskExecutor { +public: + void virtual restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) = 0; +}; + +class SharedRestorePreservedMarksTaskExecutor : public RestorePreservedMarksTaskExecutor { +private: + WorkGang* _workers; + +public: + SharedRestorePreservedMarksTaskExecutor(WorkGang* workers) : _workers(workers) { } + + void restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr); + +}; + +class PreservedMarksSet : public CHeapObj { +private: + // true -> _stacks will be allocated in the C heap + // false -> _stacks will be allocated in the resource arena + const bool _in_c_heap; + + // Number of stacks we have allocated (typically, one stack per GC worker). + // This should be >= 1 if the stacks have been initialized, + // or == 0 if they have not. + uint _num; + + // Stack array (typically, one stack per GC worker) of length _num. + // This should be != NULL if the stacks have been initialized, + // or == NULL if they have not. + Padded* _stacks; + +public: + uint num() const { return _num; } + + // Return the i'th stack. + PreservedMarks* get(uint i = 0) const { + assert(_num > 0 && _stacks != NULL, "stacks should have been initialized"); + assert(i < _num, "pre-condition"); + return (_stacks + i); + } + + // Allocate stack array. + void init(uint num); + + // Iterate over all stacks, restore all preserved marks, and reclaim + // the memory taken up by the stack segments. + // Supported executors: SharedRestorePreservedMarksTaskExecutor (Serial, CMS, G1), + // PSRestorePreservedMarksTaskExecutor (PS). + inline void restore(RestorePreservedMarksTaskExecutor* executor); + + // Reclaim stack array. + void reclaim(); + + // Assert all the stacks are empty and have no cached segments. + void assert_empty() PRODUCT_RETURN; + + PreservedMarksSet(bool in_c_heap) + : _in_c_heap(in_c_heap), _num(0), _stacks(NULL) { } + + ~PreservedMarksSet() { + assert(_stacks == NULL && _num == 0, "stacks should have been reclaimed"); + } +}; + +#endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.inline.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/preservedMarks.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP +#define SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP + +#include "gc_implementation/shenandoah/preservedMarks.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" +#include "oops/oop.inline.hpp" +#include "utilities/stack.inline.hpp" + +inline bool PreservedMarks::should_preserve_mark(oop obj, markOop m) const { + return m->must_be_preserved_for_promotion_failure(obj); +} + +inline void PreservedMarks::push(oop obj, markOop m) { + assert(should_preserve_mark(obj, m), "pre-condition"); + OopAndMarkOop elem(obj, m); + _stack.push(elem); +} + +inline void PreservedMarks::push_if_necessary(oop obj, markOop m) { + if (should_preserve_mark(obj, m)) { + push(obj, m); + } +} + +inline void PreservedMarks::init_forwarded_mark(oop obj) { + obj->init_mark(); +} + +inline void PreservedMarksSet::restore(RestorePreservedMarksTaskExecutor* executor) { + volatile size_t total_size = 0; + +#ifdef ASSERT + // This is to make sure the total_size we'll calculate below is correct. + size_t total_size_before = 0; + for (uint i = 0; i < _num; i += 1) { + total_size_before += get(i)->size(); + } +#endif // def ASSERT + + executor->restore(this, &total_size); + assert_empty(); + + assert(total_size == total_size_before, + err_msg("total_size = " SIZE_FORMAT " before = " SIZE_FORMAT, + total_size, total_size_before)); + + log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size); +} + +inline PreservedMarks::PreservedMarks() + : _stack(OopAndMarkOopStack::default_segment_size(), + // This stack should be used very infrequently so there's + // no point in caching stack segments (there will be a + // waste of space most of the time). So we set the max + // cache size to 0. + 0 /* max_cache_size */) { } + +void PreservedMarks::OopAndMarkOop::set_mark() const { + _o->set_mark(_m); +} + +#endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahAsserts.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahAsserts.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahAsserts.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahAsserts.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,9 +24,11 @@ #include "precompiled.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegionSet.inline.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" #include "gc_implementation/shenandoah/shenandoahUtils.hpp" #include "memory/resourceArea.hpp" @@ -58,12 +60,19 @@ stringStream ss; r->print_on(&ss); + stringStream mw_ss; + obj->mark()->print_on(&mw_ss); + ShenandoahMarkingContext* const ctx = heap->marking_context(); msg.append(" " PTR_FORMAT " - klass " PTR_FORMAT " %s\n", p2i(obj), p2i(obj->klass()), obj->klass()->external_name()); msg.append(" %3s allocated after mark start\n", ctx->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + if (heap->traversal_gc() != NULL) { + msg.append(" %3s in traversal set\n", heap->traversal_gc()->traversal_set()->is_in((HeapWord*) obj) ? "" : "not"); + } msg.append(" %3s marked \n", ctx->is_marked(obj) ? "" : "not"); msg.append(" %3s in collection set\n", heap->in_collection_set(obj) ? "" : "not"); + msg.append(" mark:%s\n", mw_ss.as_string()); msg.append(" region: %s", ss.as_string()); } @@ -131,9 +140,9 @@ msg.append("\n"); if (level >= _safe_oop) { - oop fwd = (oop) ShenandoahBrooksPointer::get_raw_unchecked(obj); + oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj); msg.append("Forwardee:\n"); - if (!oopDesc::unsafe_equals(obj, fwd)) { + if (obj != fwd) { if (level >= _safe_oop_fwd) { print_obj(msg, fwd); } else { @@ -146,9 +155,9 @@ } if (level >= _safe_oop_fwd) { - oop fwd = (oop) ShenandoahBrooksPointer::get_raw_unchecked(obj); - oop fwd2 = (oop) ShenandoahBrooksPointer::get_raw_unchecked(fwd); - if (!oopDesc::unsafe_equals(fwd, fwd2)) { + oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj); + oop fwd2 = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(fwd); + if (fwd != fwd2) { msg.append("Second forwardee:\n"); print_obj_safe(msg, fwd2); msg.append("\n"); @@ -192,9 +201,9 @@ file,line); } - oop fwd = oop(ShenandoahBrooksPointer::get_raw_unchecked(obj)); + oop fwd = oop(ShenandoahForwarding::get_forwardee_raw_unchecked(obj)); - if (!oopDesc::unsafe_equals(obj, fwd)) { + if (obj != fwd) { // When Full GC moves the objects, we cannot trust fwdptrs. If we got here, it means something // tries fwdptr manipulation when Full GC is running. The only exception is using the fwdptr // that still points to the object itself. @@ -225,8 +234,8 @@ } // Step 4. Check for multiple forwardings - oop fwd2 = oop(ShenandoahBrooksPointer::get_raw_unchecked(fwd)); - if (!oopDesc::unsafe_equals(fwd, fwd2)) { + oop fwd2 = oop(ShenandoahForwarding::get_forwardee_raw_unchecked(fwd)); + if (fwd != fwd2) { print_failure(_safe_all, obj, interior_loc, NULL, "Shenandoah assert_correct failed", "Multiple forwardings", file, line); @@ -245,7 +254,7 @@ file, line); } - size_t alloc_size = obj->size() + ShenandoahBrooksPointer::word_size(); + size_t alloc_size = obj->size(); if (alloc_size > ShenandoahHeapRegion::humongous_threshold_words()) { size_t idx = r->region_number(); size_t num_regions = ShenandoahHeapRegion::required_regions(alloc_size * HeapWordSize); @@ -267,9 +276,9 @@ void ShenandoahAsserts::assert_forwarded(void* interior_loc, oop obj, const char* file, int line) { assert_correct(interior_loc, obj, file, line); - oop fwd = oop(ShenandoahBrooksPointer::get_raw_unchecked(obj)); + oop fwd = oop(ShenandoahForwarding::get_forwardee_raw_unchecked(obj)); - if (oopDesc::unsafe_equals(obj, fwd)) { + if (obj == fwd) { print_failure(_safe_all, obj, interior_loc, NULL, "Shenandoah assert_forwarded failed", "Object should be forwarded", file, line); @@ -278,9 +287,9 @@ void ShenandoahAsserts::assert_not_forwarded(void* interior_loc, oop obj, const char* file, int line) { assert_correct(interior_loc, obj, file, line); - oop fwd = oop(ShenandoahBrooksPointer::get_raw_unchecked(obj)); + oop fwd = oop(ShenandoahForwarding::get_forwardee_raw_unchecked(obj)); - if (!oopDesc::unsafe_equals(obj, fwd)) { + if (obj != fwd) { print_failure(_safe_all, obj, interior_loc, NULL, "Shenandoah assert_not_forwarded failed", "Object should not be forwarded", file, line); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetAssembler_stub.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetAssembler_stub.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetAssembler_stub.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetAssembler_stub.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_STUB_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_STUB_HPP + +#include "asm/macroAssembler.hpp" +#include "memory/allocation.hpp" + +class ShenandoahBarrierSetAssembler : public CHeapObj { + +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_STUB_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_LIRGenerator.hpp" +#include "c1/c1_IR.hpp" +#include "gc_implementation/g1/satbQueue.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" + +#ifdef TARGET_ARCH_aarch64 +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#endif +#ifdef TARGET_ARCH_x86 +#include "shenandoahBarrierSetAssembler_x86.hpp" +#endif + +#ifndef PATCHED_ADDR +#define PATCHED_ADDR (max_jint) +#endif + +#ifdef ASSERT +#define __ gen->lir(__FILE__, __LINE__)-> +#else +#define __ gen->lir()-> +#endif + +void ShenandoahLoadReferenceBarrierStub::emit_code(LIR_Assembler* ce) { + ShenandoahBarrierSetAssembler* bs = ShenandoahBarrierSetAssembler::bsasm(); + bs->gen_load_reference_barrier_stub(ce, this); +} + +ShenandoahBarrierSetC1* ShenandoahBarrierSetC1::bsc1() { + return ShenandoahBarrierSet::barrier_set()->bsc1(); +} + +LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { + if (ShenandoahLoadRefBarrier) { + return load_reference_barrier_impl(gen, obj, info, need_null_check); + } else { + return obj; + } +} + +LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { + assert(ShenandoahLoadRefBarrier, "Should be enabled"); + obj = ensure_in_register(gen, obj); + assert(obj->is_register(), "must be a register at this point"); + LIR_Opr result = gen->new_register(T_OBJECT); + __ move(obj, result); + + LIR_Opr thrd = gen->getThreadPointer(); + LIR_Address* active_flag_addr = + new LIR_Address(thrd, + in_bytes(JavaThread::gc_state_offset()), + T_BYTE); + // Read and check the gc-state-flag. + LIR_Opr flag_val = gen->new_register(T_INT); + __ load(active_flag_addr, flag_val); + LIR_Opr mask = LIR_OprFact::intConst(ShenandoahHeap::HAS_FORWARDED | + ShenandoahHeap::EVACUATION); + LIR_Opr mask_reg = gen->new_register(T_INT); + __ move(mask, mask_reg); + + if (TwoOperandLIRForm) { + __ logical_and(flag_val, mask_reg, flag_val); + } else { + LIR_Opr masked_flag = gen->new_register(T_INT); + __ logical_and(flag_val, mask_reg, masked_flag); + flag_val = masked_flag; + } + __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); + + CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result, info ? new CodeEmitInfo(info) : NULL, need_null_check); + __ branch(lir_cond_notEqual, T_INT, slow); + __ branch_destination(slow->continuation()); + + return result; +} + +LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRGenerator* gen, LIR_Opr obj) { + if (!obj->is_register()) { + LIR_Opr obj_reg = gen->new_register(T_OBJECT); + if (obj->is_constant()) { + __ move(obj, obj_reg); + } else { + __ leal(obj, obj_reg); + } + obj = obj_reg; + } + return obj; +} + +LIR_Opr ShenandoahBarrierSetC1::storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool patch) { + if (ShenandoahStoreValEnqueueBarrier) { + obj = ensure_in_register(gen, obj); + gen->G1SATBCardTableModRef_pre_barrier(LIR_OprFact::illegalOpr, obj, false, false, NULL); + } + return obj; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_C1_SHENANDOAHBARRIERSETC1_HPP +#define SHARE_GC_SHENANDOAH_C1_SHENANDOAHBARRIERSETC1_HPP + +#include "c1/c1_CodeStubs.hpp" +#include "memory/allocation.hpp" + +class LIRGenerator; + +class ShenandoahLoadReferenceBarrierStub: public CodeStub { + friend class ShenandoahBarrierSetC1; +private: + LIR_Opr _obj; + LIR_Opr _result; + CodeEmitInfo* _info; + bool _needs_null_check; + +public: + ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr result, CodeEmitInfo* info, bool needs_null_check) : + _obj(obj), _result(result), _info(info), _needs_null_check(needs_null_check) + { + assert(_obj->is_register(), "should be register"); + assert(_result->is_register(), "should be register"); + } + + LIR_Opr obj() const { return _obj; } + LIR_Opr result() const { return _result; } + CodeEmitInfo* info() const { return _info; } + bool needs_null_check() const { return _needs_null_check; } + + virtual void emit_code(LIR_Assembler* e); + virtual void visit(LIR_OpVisitState* visitor) { + visitor->do_slow_case(); + visitor->do_input(_obj); + visitor->do_temp(_result); + } +#ifndef PRODUCT + virtual void print_name(outputStream* out) const { out->print("ShenandoahLoadReferenceBarrierStub"); } +#endif // PRODUCT +}; + +class ShenandoahBarrierSetC1 : public CHeapObj{ +private: + CodeBlob* _pre_barrier_c1_runtime_code_blob; +public: + static ShenandoahBarrierSetC1* bsc1(); + + LIR_Opr load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check); + LIR_Opr storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool patch); +private: + LIR_Opr load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check); + LIR_Opr ensure_in_register(LIRGenerator* gen, LIR_Opr obj); + +}; + +#endif // SHARE_GC_SHENANDOAH_C1_SHENANDOAHBARRIERSETC1_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahRuntime.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#include "opto/type.hpp" +#include "runtime/thread.hpp" + +ShenandoahBarrierSetC2* ShenandoahBarrierSetC2::bsc2() { + return ShenandoahBarrierSet::barrier_set()->bsc2(); +} + +bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) { + return call->is_CallLeaf() && + call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT); +} + +bool ShenandoahBarrierSetC2::is_shenandoah_state_load(Node* n) { + if (!n->is_Load()) return false; + const int state_offset = in_bytes(JavaThread::gc_state_offset()); + return n->in(2)->is_AddP() && n->in(2)->in(2)->Opcode() == Op_ThreadLocal + && n->in(2)->in(3)->is_Con() + && n->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == state_offset; +} + +const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() { + const Type **fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value + const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); + + // create result type (range) + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); + + return TypeFunc::make(domain, range); +} + +Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) { + if (c->Opcode() == Op_ShenandoahLoadReferenceBarrier) { + return c->in(ShenandoahLoadReferenceBarrierNode::ValueIn); + } + return c; +} + +Node* ShenandoahBarrierSetC2::load_reference_barrier(GraphKit* kit, Node* n) const { + if (ShenandoahLoadRefBarrier) { + return kit->gvn().transform(new (kit->C) ShenandoahLoadReferenceBarrierNode(NULL, n)); + } else { + return n; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_C2_SHENANDOAHBARRIERSETC2_HPP +#define SHARE_GC_SHENANDOAH_C2_SHENANDOAHBARRIERSETC2_HPP + +#include "memory/allocation.hpp" + +class GraphKit; +class Node; +class TypeFunc; + +class ShenandoahBarrierSetC2 : public CHeapObj { +public: + static ShenandoahBarrierSetC2* bsc2(); + + static bool is_shenandoah_lrb_call(Node* call); + static bool is_shenandoah_state_load(Node* n); + + static const TypeFunc* shenandoah_load_reference_barrier_Type(); + + Node* step_over_gc_barrier(Node* c); + + Node* load_reference_barrier(GraphKit* kit, Node* n) const; +}; + +#endif // SHARE_GC_SHENANDOAH_C2_SHENANDOAHBARRIERSETC2_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -29,7 +29,24 @@ #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" #include "runtime/interfaceSupport.hpp" +#include "utilities/macros.hpp" +#ifdef COMPILER1 +#include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp" +#endif +#ifdef COMPILER2 +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#endif + +#if defined(TARGET_ARCH_aarch64) +#include "shenandoahBarrierSetAssembler_aarch64.hpp" +#elif defined(TARGET_ARCH_x86) +#include "shenandoahBarrierSetAssembler_x86.hpp" +#else +#include "shenandoahBarrierSetAssembler_stub.hpp" +#endif + +template class ShenandoahUpdateRefsForOopClosure: public ExtendedOopClosure { private: ShenandoahHeap* _heap; @@ -37,23 +54,47 @@ template inline void do_oop_work(T* p) { - _heap->maybe_update_with_forwarded(p); + oop o; + if (STOREVAL_EVAC_BARRIER) { + o = _heap->evac_update_with_forwarded(p); + if (!oopDesc::is_null(o)) { + _bs->enqueue(o); + } + } else { + _heap->maybe_update_with_forwarded(p); + } } public: ShenandoahUpdateRefsForOopClosure() : _heap(ShenandoahHeap::heap()), _bs(ShenandoahBarrierSet::barrier_set()) { assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled"); } - void do_oop(oop* p) { do_oop_work(p); } - void do_oop(narrowOop* p) { do_oop_work(p); } + + virtual void do_oop(oop* p) { do_oop_work(p); } + virtual void do_oop(narrowOop* p) { do_oop_work(p); } }; ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) : BarrierSet(), - _heap(heap) + _heap(heap), + _bsasm(new ShenandoahBarrierSetAssembler()), + _bsc1(COMPILER1_PRESENT(new ShenandoahBarrierSetC1()) NOT_COMPILER1(NULL)), + _bsc2(COMPILER2_PRESENT(new ShenandoahBarrierSetC2()) NOT_COMPILER2(NULL)) { _kind = BarrierSet::ShenandoahBarrierSet; } +ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::bsasm() const { + return _bsasm; +} + +ShenandoahBarrierSetC1* ShenandoahBarrierSet::bsc1() const { + return _bsc1; +} + +ShenandoahBarrierSetC2* ShenandoahBarrierSet::bsc2() const { + return _bsc2; +} + void ShenandoahBarrierSet::print_on(outputStream* st) const { st->print("ShenandoahBarrierSet"); } @@ -119,10 +160,10 @@ // return *v; } -template +template void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) { - assert(UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled"); - ShenandoahUpdateRefsForOopClosure cl; + assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled"); + ShenandoahUpdateRefsForOopClosure cl; T* dst = (T*) start; for (size_t i = 0; i < count; i++) { cl.do_oop(dst++); @@ -134,11 +175,19 @@ if (!ShenandoahCloneBarrier) return; if (!need_update_refs_barrier()) return; - ShenandoahEvacOOMScope oom_evac_scope; - if (UseCompressedOops) { - write_ref_array_loop(start, count); + if (_heap->is_concurrent_traversal_in_progress()) { + ShenandoahEvacOOMScope oom_evac_scope; + if (UseCompressedOops) { + write_ref_array_loop(start, count); + } else { + write_ref_array_loop(start, count); + } } else { - write_ref_array_loop(start, count); + if (UseCompressedOops) { + write_ref_array_loop(start, count); + } else { + write_ref_array_loop(start, count); + } } } @@ -171,28 +220,25 @@ } template -void ShenandoahBarrierSet::write_ref_field_pre_static(T* field, oop newVal) { - T heap_oop = oopDesc::load_heap_oop(field); - - shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_gc()); - - if (!oopDesc::is_null(heap_oop)) { - ShenandoahBarrierSet::barrier_set()->enqueue(oopDesc::decode_heap_oop(heap_oop)); - } -} - -template inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop newVal) { - write_ref_field_pre_static(field, newVal); + newVal = load_reference_barrier(newVal); + storeval_barrier(newVal); + if (ShenandoahSATBBarrier) { + T heap_oop = oopDesc::load_heap_oop(field); + shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_gc()); + if (!oopDesc::is_null(heap_oop)) { + ShenandoahBarrierSet::barrier_set()->enqueue(oopDesc::decode_heap_oop(heap_oop)); + } + } } // These are the more general virtual versions. void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) { - write_ref_field_pre_static(field, new_val); + inline_write_ref_field_pre(field, new_val); } void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) { - write_ref_field_pre_static(field, new_val); + inline_write_ref_field_pre(field, new_val); } void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) { @@ -211,62 +257,47 @@ // it would be NULL in any case. But we *are* interested in any oop* // that potentially need to be updated. - ShenandoahEvacOOMScope oom_evac_scope; oop obj = oop(mr.start()); shenandoah_assert_correct(NULL, obj); - ShenandoahUpdateRefsForOopClosure cl; - obj->oop_iterate(&cl); -} - -oop ShenandoahBarrierSet::read_barrier(oop src) { - // Check for forwarded objects, because on Full GC path we might deal with - // non-trivial fwdptrs that contain Full GC specific metadata. We could check - // for is_full_gc_in_progress(), but this also covers the case of stable heap, - // which provides a bit of performance improvement. - if (ShenandoahReadBarrier && _heap->has_forwarded_objects()) { - return ShenandoahBarrierSet::resolve_forwarded(src); + if (_heap->is_concurrent_traversal_in_progress()) { + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahUpdateRefsForOopClosure cl; + obj->oop_iterate(&cl); } else { - return src; + ShenandoahUpdateRefsForOopClosure cl; + obj->oop_iterate(&cl); } } -bool ShenandoahBarrierSet::obj_equals(oop obj1, oop obj2) { - bool eq = oopDesc::unsafe_equals(obj1, obj2); - if (! eq && ShenandoahAcmpBarrier) { - OrderAccess::loadload(); - obj1 = resolve_forwarded(obj1); - obj2 = resolve_forwarded(obj2); - eq = oopDesc::unsafe_equals(obj1, obj2); +oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) { + assert(obj != NULL, ""); + if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) { + return load_reference_barrier_impl(obj); + } else { + return obj; } - return eq; } -bool ShenandoahBarrierSet::obj_equals(narrowOop obj1, narrowOop obj2) { - return obj_equals(oopDesc::decode_heap_oop(obj1), oopDesc::decode_heap_oop(obj2)); +oop ShenandoahBarrierSet::load_reference_barrier(oop obj) { + if (obj != NULL) { + return load_reference_barrier_not_null(obj); + } else { + return obj; + } } -JRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_JRT(oopDesc* src)) - oop result = ShenandoahBarrierSet::barrier_set()->write_barrier_mutator(src); - return (oopDesc*) result; -JRT_END - -IRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_IRT(oopDesc* src)) - oop result = ShenandoahBarrierSet::barrier_set()->write_barrier_mutator(src); - return (oopDesc*) result; -IRT_END -oop ShenandoahBarrierSet::write_barrier_mutator(oop obj) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled"); - assert(_heap->is_gc_in_progress_mask(ShenandoahHeap::EVACUATION), "evac should be in progress"); +oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj) { + assert(ShenandoahLoadRefBarrier, "should be enabled"); + assert(_heap->is_gc_in_progress_mask(ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL), "evac should be in progress"); shenandoah_assert_in_cset(NULL, obj); oop fwd = resolve_forwarded_not_null(obj); - if (oopDesc::unsafe_equals(obj, fwd)) { + if (obj == fwd) { ShenandoahEvacOOMScope oom_evac_scope; - bool evac; Thread* thread = Thread::current(); - oop res_oop = _heap->evacuate_object(obj, thread, evac); + oop res_oop = _heap->evacuate_object(obj, thread); // Since we are already here and paid the price of getting through runtime call adapters // and acquiring oom-scope, it makes sense to try and evacuate more adjacent objects, @@ -278,20 +309,23 @@ size_t max = ShenandoahEvacAssist; if (max > 0) { - ShenandoahMarkingContext* ctx = _heap->complete_marking_context(); + // Traversal is special: it uses incomplete marking context, because it coalesces evac with mark. + // Other code uses complete marking context, because evac happens after the mark. + ShenandoahMarkingContext* ctx = _heap->is_concurrent_traversal_in_progress() ? + _heap->marking_context() : _heap->complete_marking_context(); ShenandoahHeapRegion* r = _heap->heap_region_containing(obj); assert(r->is_cset(), "sanity"); - HeapWord* cur = (HeapWord*)obj + obj->size() + ShenandoahBrooksPointer::word_size(); + HeapWord* cur = (HeapWord*)obj + obj->size(); size_t count = 0; while ((cur < r->top()) && ctx->is_marked(oop(cur)) && (count++ < max)) { oop cur_oop = oop(cur); - if (oopDesc::unsafe_equals(cur_oop, resolve_forwarded_not_null(cur_oop))) { - _heap->evacuate_object(cur_oop, thread, evac); + if (cur_oop == resolve_forwarded_not_null(cur_oop)) { + _heap->evacuate_object(cur_oop, thread); } - cur = cur + cur_oop->size() + ShenandoahBrooksPointer::word_size(); + cur = cur + cur_oop->size(); } } @@ -300,31 +334,44 @@ return fwd; } -oop ShenandoahBarrierSet::write_barrier(oop obj) { - if (ShenandoahWriteBarrier && _heap->has_forwarded_objects()) { - if (!oopDesc::is_null(obj)) { - bool evac_in_progress = _heap->is_evacuation_in_progress(); - oop fwd = resolve_forwarded_not_null(obj); - if (evac_in_progress && - _heap->in_collection_set(obj) && - oopDesc::unsafe_equals(obj, fwd)) { - Thread *t = Thread::current(); - bool evac; - if (t->is_Worker_thread()) { - return _heap->evacuate_object(obj, t, evac); - } else { - ShenandoahEvacOOMScope oom_evac_scope; - return _heap->evacuate_object(obj, t, evac); - } +oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { + assert(ShenandoahLoadRefBarrier, "should be enabled"); + if (!oopDesc::is_null(obj)) { + bool evac_in_progress = _heap->is_gc_in_progress_mask(ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL); + oop fwd = resolve_forwarded_not_null(obj); + if (evac_in_progress && + _heap->in_collection_set(obj) && + obj == fwd) { + Thread *t = Thread::current(); + if (t->is_GC_task_thread()) { + return _heap->evacuate_object(obj, t); } else { - return fwd; + ShenandoahEvacOOMScope oom_evac_scope; + return _heap->evacuate_object(obj, t); } + } else { + return fwd; } + } else { + return obj; + } +} + +void ShenandoahBarrierSet::storeval_barrier(oop obj) { + if (ShenandoahStoreValEnqueueBarrier && !oopDesc::is_null(obj) && _heap->is_concurrent_traversal_in_progress()) { + enqueue(obj); + } +} + +void ShenandoahBarrierSet::keep_alive_barrier(oop obj) { + if (ShenandoahKeepAliveBarrier && _heap->is_concurrent_mark_in_progress()) { + enqueue(obj); } - return obj; } void ShenandoahBarrierSet::enqueue(oop obj) { + shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_traversal_in_progress()); + // Filter marked objects before hitting the SATB queues. The same predicate would // be used by SATBMQ::filter to eliminate already marked objects downstream, but // filtering here helps to avoid wasteful SATB queueing work to begin with. @@ -332,3 +379,37 @@ G1SATBCardTableModRefBS::enqueue(obj); } + +oop ShenandoahBarrierSet::atomic_compare_exchange_oop(oop exchange_value, + volatile HeapWord *dest, + oop compare_value) { + if (UseCompressedOops) { + // encode exchange and compare value from oop to T + narrowOop val = oopDesc::encode_heap_oop(exchange_value); + narrowOop cmp = oopDesc::encode_heap_oop(compare_value); + + narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp); + // decode old from T to oop + return oopDesc::decode_heap_oop(old); + } else { + return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value); + } +} + +oop ShenandoahBarrierSet::oop_atomic_cmpxchg_in_heap(oop new_value, volatile HeapWord* dest, oop compare_value) { + oop expected; + bool success; + do { + expected = compare_value; + compare_value = atomic_compare_exchange_oop(new_value, dest, expected); + success = (compare_value == expected); + } while ((! success) && resolve_forwarded(compare_value) == resolve_forwarded(expected)); + oop result = load_reference_barrier(compare_value); + if (ShenandoahSATBBarrier && success && result != NULL) { + enqueue(result); + } + if (new_value != NULL) { + storeval_barrier(new_value); + } + return result; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,11 +27,17 @@ #include "memory/barrierSet.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" +class ShenandoahBarrierSetAssembler; +class ShenandoahBarrierSetC1; +class ShenandoahBarrierSetC2; class ShenandoahHeap; class ShenandoahBarrierSet: public BarrierSet { private: ShenandoahHeap* _heap; + ShenandoahBarrierSetAssembler* const _bsasm; + ShenandoahBarrierSetC1* const _bsc1; + ShenandoahBarrierSetC2* const _bsc2; public: ShenandoahBarrierSet(ShenandoahHeap* heap); @@ -42,6 +48,10 @@ return (ShenandoahBarrierSet*)bs; } + ShenandoahBarrierSetAssembler* bsasm() const; + ShenandoahBarrierSetC1* bsc1() const; + ShenandoahBarrierSetC2* bsc2() const; + void print_on(outputStream* st) const; bool is_a(BarrierSet::Name bsn); @@ -81,8 +91,6 @@ void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized); - template static void write_ref_field_pre_static(T* field, oop newVal); - // We export this to make it available in cases where the static // type of the barrier set is known. Note that it is non-virtual. template inline void inline_write_ref_field_pre(T* field, oop newVal); @@ -95,36 +103,31 @@ void write_ref_field_work(void* v, oop o, bool release = false); void write_region_work(MemRegion mr); - virtual oop read_barrier(oop src); - static inline oop resolve_forwarded_not_null(oop p); static inline oop resolve_forwarded(oop p); - virtual oop write_barrier(oop obj); - static oopDesc* write_barrier_IRT(oopDesc* src); - static oopDesc* write_barrier_JRT(oopDesc* src); + void storeval_barrier(oop obj); + void keep_alive_barrier(oop obj); - oop write_barrier_mutator(oop obj); + oop load_reference_barrier(oop obj); + oop load_reference_barrier_mutator(oop obj); + oop load_reference_barrier_not_null(oop obj); - bool obj_equals(oop obj1, oop obj2); - bool obj_equals(narrowOop obj1, narrowOop obj2); + oop oop_atomic_cmpxchg_in_heap(oop new_value, volatile HeapWord* dest, oop compare_value); void enqueue(oop obj); private: inline bool need_update_refs_barrier(); - template + template void write_ref_array_loop(HeapWord* start, size_t count); -#ifndef CC_INTERP -public: - virtual void interpreter_read_barrier(MacroAssembler* masm, Register dst); - virtual void interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst); - void interpreter_write_barrier(MacroAssembler* masm, Register dst); - void asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2); + oop load_reference_barrier_impl(oop obj); -#endif + oop atomic_compare_exchange_oop(oop exchange_value, + volatile HeapWord *dest, + oop compare_value); }; #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,7 @@ #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" bool ShenandoahBarrierSet::need_update_refs_barrier() { @@ -33,7 +34,7 @@ } inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) { - return ShenandoahBrooksPointer::forwardee(p); + return ShenandoahForwarding::get_forwardee(p); } inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_HPP -#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_HPP - -#include "oops/oop.hpp" -#include "utilities/globalDefinitions.hpp" - -class ShenandoahBrooksPointer { - /* - * Notes: - * - * a. It is important to have byte_offset and word_offset return constant - * expressions, because that will allow to constant-fold forwarding ptr - * accesses. This is not a problem in JIT compilers that would generate - * the code once, but it is problematic in GC hotpath code. - * - * b. With filler object mechanics, we may need to allocate more space for - * the forwarding ptr to meet alignment requirements for objects. This - * means *_offset and *_size calls are NOT interchangeable. The accesses - * to forwarding ptrs should always be via *_offset. Storage size - * calculations should always be via *_size. - */ - -public: - /* Offset from the object start, in HeapWords. */ - static inline int word_offset() { - return -1; // exactly one HeapWord - } - - /* Offset from the object start, in bytes. */ - static inline int byte_offset() { - return -HeapWordSize; // exactly one HeapWord - } - - /* Allocated size, in HeapWords. */ - static inline uint word_size() { - return (uint) MinObjAlignment; - } - - /* Allocated size, in bytes */ - static inline uint byte_size() { - return (uint) MinObjAlignmentInBytes; - } - - /* Assert basic stuff once at startup. */ - static void initial_checks() { - guarantee (MinObjAlignment > 0, "sanity, word_size is correct"); - guarantee (MinObjAlignmentInBytes > 0, "sanity, byte_size is correct"); - } - - /* Initializes Brooks pointer (to self). - */ - static inline void initialize(oop obj); - - /* Gets forwardee from the given object. - */ - static inline oop forwardee(oop obj); - - /* Tries to atomically update forwardee in $holder object to $update. - * Assumes $holder points at itself. - * Asserts $holder is in from-space. - * Asserts $update is in to-space. - */ - static inline oop try_update_forwardee(oop obj, oop update); - - /* Sets raw value for forwardee slot. - * THIS IS DANGEROUS: USERS HAVE TO INITIALIZE/SET FORWARDEE BACK AFTER THEY ARE DONE. - */ - static inline void set_raw(oop obj, HeapWord* update); - - /* Returns the raw value from forwardee slot. - */ - static inline HeapWord* get_raw(oop obj); - - /* Returns the raw value from forwardee slot without any checks. - * Used for quick verification. - */ - static inline HeapWord* get_raw_unchecked(oop obj); - -private: - static inline HeapWord** brooks_ptr_addr(oop obj); -}; - -#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahBrooksPointer.inline.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_INLINE_HPP -#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_INLINE_HPP - -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahAsserts.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" -#include "gc_implementation/shenandoah/shenandoahLogging.hpp" -#include "runtime/atomic.hpp" - -inline HeapWord** ShenandoahBrooksPointer::brooks_ptr_addr(oop obj) { - return (HeapWord**)((HeapWord*) obj + word_offset()); -} - -inline void ShenandoahBrooksPointer::initialize(oop obj) { - shenandoah_assert_in_heap(NULL, obj); - *brooks_ptr_addr(obj) = (HeapWord*) obj; -} - -inline void ShenandoahBrooksPointer::set_raw(oop obj, HeapWord* update) { - shenandoah_assert_in_heap(NULL, obj); - *brooks_ptr_addr(obj) = update; -} - -inline HeapWord* ShenandoahBrooksPointer::get_raw(oop obj) { - shenandoah_assert_in_heap(NULL, obj); - return *brooks_ptr_addr(obj); -} - -inline HeapWord* ShenandoahBrooksPointer::get_raw_unchecked(oop obj) { - return *brooks_ptr_addr(obj); -} - -inline oop ShenandoahBrooksPointer::forwardee(oop obj) { - shenandoah_assert_correct(NULL, obj); - return oop(*brooks_ptr_addr(obj)); -} - -inline oop ShenandoahBrooksPointer::try_update_forwardee(oop obj, oop update) { - oop result = (oop) Atomic::cmpxchg_ptr(update, brooks_ptr_addr(obj), obj); - shenandoah_assert_correct_except(NULL, obj, !oopDesc::unsafe_equals(result, obj)); - return result; -} - -#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHBROOKSPOINTER_INLINE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahClosures.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahClosures.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahClosures.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahClosures.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -38,7 +38,8 @@ } obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); shenandoah_assert_not_forwarded_if(NULL, obj, - ShenandoahHeap::heap()->is_concurrent_mark_in_progress()); + (ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || + ShenandoahHeap::heap()->is_concurrent_traversal_in_progress())); return _mark_context->is_marked(obj); } @@ -90,9 +91,8 @@ if (_heap->in_collection_set(obj)) { shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); - if (oopDesc::unsafe_equals(resolved, obj)) { - bool evac; - resolved = _heap->evacuate_object(obj, _thread, evac); + if (resolved == obj) { + resolved = _heap->evacuate_object(obj, _thread); } oopDesc::encode_store_heap_oop(p, resolved); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,6 +27,7 @@ #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahCodeRoots.hpp" #include "memory/resourceArea.hpp" +#include "runtime/vmThread.hpp" ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator() : _claimed_idx(0), _finished(false) { @@ -102,33 +103,6 @@ } }; -class ShenandoahNMethodOopInitializer : public OopClosure { -public: - ShenandoahNMethodOopInitializer() {}; - -private: - template - inline void do_oop_work(T* p) { - T o = oopDesc::load_heap_oop(p); - if (! oopDesc::is_null(o)) { - oop obj1 = oopDesc::decode_heap_oop_not_null(o); - oop obj2 = oopDesc::bs()->write_barrier(obj1); - if (! oopDesc::unsafe_equals(obj1, obj2)) { - shenandoah_assert_not_in_cset(NULL, obj2); - oopDesc::encode_store_heap_oop(p, obj2); - } - } - } - -public: - void do_oop(oop* o) { - do_oop_work(o); - } - void do_oop(narrowOop* o) { - do_oop_work(o); - } -}; - ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock; GrowableArray* ShenandoahCodeRoots::_recorded_nms; @@ -140,21 +114,13 @@ void ShenandoahCodeRoots::add_nmethod(nmethod* nm) { switch (ShenandoahCodeRootsStyle) { case 0: - case 1: { - ShenandoahNMethodOopInitializer init; - nm->oops_do(&init); - nm->fix_oop_relocations(); + case 1: break; - } case 2: { ShenandoahNMethodOopDetector detector; nm->oops_do(&detector); if (detector.has_oops()) { - ShenandoahNMethodOopInitializer init; - nm->oops_do(&init); - nm->fix_oop_relocations(); - ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops()); nmr->assert_alive_and_correct(); @@ -334,9 +300,13 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); for (int c = 0; c < _oops_count; c++) { oop *loc = _oops[c]; - assert(_nm->code_contains((address)loc) || _nm->oops_contains(loc), "nmethod should contain the oop*"); + assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*"); oop o = oopDesc::load_heap_oop(loc); - shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress()); + shenandoah_assert_correct_except(loc, o, + o == NULL || + heap->is_full_gc_move_in_progress() || + (VMThread::vm_operation() != NULL) && (VMThread::vm_operation()->type() == VM_Operation::VMOp_HeapWalkOperation) + ); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -105,7 +105,7 @@ void possibly_parallel_blobs_do(CodeBlobClosure* f); }; -class ShenandoahCodeRoots : public CHeapObj { +class ShenandoahCodeRoots : public AllStatic { friend class ShenandoahHeap; friend class ShenandoahCodeRootsLock; friend class ShenandoahCodeRootsIterator; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,7 +28,6 @@ #include "code/codeCache.hpp" #include "gc_implementation/shared/parallelCleaning.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc_implementation/shenandoah/shenandoahClosures.inline.hpp" #include "gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp" @@ -129,11 +128,10 @@ CLDToOopClosure clds_cl(oops); MarkingCodeBlobClosure blobs_cl(oops, ! CodeBlobToOopClosure::FixRelocations); - OopClosure* weak_oops = _process_refs ? NULL : oops; ResourceMark m; if (heap->unload_classes()) { - _rp->process_strong_roots(oops, weak_oops, &clds_cl, NULL, &blobs_cl, NULL, worker_id); + _rp->process_strong_roots(oops, &clds_cl, NULL, &blobs_cl, NULL, worker_id); } else { if (ShenandoahConcurrentScanCodeRoots) { CodeBlobClosure* code_blobs = NULL; @@ -146,9 +144,9 @@ code_blobs = &assert_to_space; } #endif - _rp->process_all_roots(oops, weak_oops, &clds_cl, code_blobs, NULL, worker_id); + _rp->process_all_roots(oops, &clds_cl, code_blobs, NULL, worker_id); } else { - _rp->process_all_roots(oops, weak_oops, &clds_cl, &blobs_cl, NULL, worker_id); + _rp->process_all_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id); } } } @@ -186,7 +184,7 @@ DEBUG_ONLY(&assert_to_space) NOT_DEBUG(NULL); } - _rp->process_all_roots(&cl, &cl, &cldCl, code_blobs, NULL, worker_id); + _rp->process_all_roots(&cl, &cldCl, code_blobs, NULL, worker_id); } }; @@ -465,13 +463,16 @@ // When we're done marking everything, we process weak references. if (_heap->process_references()) { weak_refs_work(full_gc); + } else { + cleanup_jni_refs(); } // And finally finish class unloading if (_heap->unload_classes()) { _heap->unload_classes_and_cleanup_tables(full_gc); + } else if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStringDedup::parallel_cleanup(); } - assert(task_queues()->is_empty(), "Should be empty"); TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats()); @@ -720,6 +721,19 @@ } } +// No-op closure. Weak JNI refs are cleaned by iterating them. +// Nothing else to do here. +class ShenandoahCleanupWeakRootsClosure : public OopClosure { + virtual void do_oop(oop* o) {} + virtual void do_oop(narrowOop* o) {} +}; + +void ShenandoahConcurrentMark::cleanup_jni_refs() { + ShenandoahIsAliveSelector is_alive; + ShenandoahCleanupWeakRootsClosure cl; + JNIHandles::weak_oops_do(is_alive.is_alive_closure(), &cl); +} + class ShenandoahCancelledGCYieldClosure : public YieldClosure { private: ShenandoahHeap* const _heap; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,6 +32,7 @@ class ShenandoahStrDedupQueue; class ShenandoahConcurrentMark: public CHeapObj { + friend class ShenandoahTraversalGC; private: ShenandoahHeap* _heap; ShenandoahObjToScanQueueSet* _task_queues; @@ -86,6 +87,7 @@ void weak_refs_work_doit(bool full_gc); public: + static void cleanup_jni_refs(); void preclean_weak_refs(); // ---------- Concurrent code cache diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,12 +24,12 @@ #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" #include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc_implementation/shenandoah/shenandoahConcurrentMark.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc_implementation/shenandoah/shenandoahStringDedup.hpp" #include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp" #include "memory/iterator.inline.hpp" @@ -40,7 +40,7 @@ void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) { oop obj = task->obj(); - shenandoah_assert_not_forwarded(NULL, obj); + shenandoah_assert_not_forwarded_except(NULL, obj, _heap->is_concurrent_traversal_in_progress() && _heap->cancelled_gc()); shenandoah_assert_marked(NULL, obj); shenandoah_assert_not_in_cset_except(NULL, obj, _heap->cancelled_gc()); @@ -70,7 +70,7 @@ inline void ShenandoahConcurrentMark::count_liveness(jushort* live_data, oop obj) { size_t region_idx = _heap->heap_region_index_containing(obj); ShenandoahHeapRegion* region = _heap->get_region(region_idx); - size_t size = obj->size() + ShenandoahBrooksPointer::word_size(); + size_t size = obj->size(); if (!region->is_humongous_start()) { assert(!region->is_humongous(), "Cannot have continuations here"); @@ -256,9 +256,12 @@ ShouldNotReachHere(); } - // Note: Only when concurrently updating references can obj become NULL here. - // It happens when a mutator thread beats us by writing another value. In that - // case we don't need to do anything else. + // Note: Only when concurrently updating references can obj be different + // (that is, really different, not just different from-/to-space copies of the same) + // from the one we originally loaded. Mutator thread can beat us by writing something + // else into the location. In that case, we would mark through that updated value, + // on the off-chance it is not handled by other means (e.g. via SATB). However, + // if that write was NULL, we don't need to do anything else. if (UPDATE_REFS != CONCURRENT || !oopDesc::is_null(obj)) { shenandoah_assert_not_forwarded(p, obj); shenandoah_assert_not_in_cset_except(p, obj, heap->cancelled_gc()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -33,6 +33,7 @@ #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" #include "gc_implementation/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc_implementation/shenandoah/shenandoahPhaseTimings.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" #include "gc_implementation/shenandoah/shenandoahUtils.hpp" #include "gc_implementation/shenandoah/shenandoahVMOperations.hpp" #include "gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp" @@ -99,6 +100,10 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); + GCMode default_mode = heap->is_traversal_mode() ? + concurrent_traversal : concurrent_normal; + GCCause::Cause default_cause = heap->is_traversal_mode() ? + GCCause::_shenandoah_traversal_gc : GCCause::_shenandoah_concurrent_gc; int sleep = ShenandoahControlIntervalMin; double last_shrink_time = os::elapsedTime(); @@ -155,8 +160,7 @@ if (ExplicitGCInvokesConcurrent) { policy->record_explicit_to_concurrent(); - mode = concurrent_normal; - + mode = default_mode; // Unload and clean up everything heap->set_process_references(heuristics->can_process_references()); heap->set_unload_classes(heuristics->can_unload_classes()); @@ -170,9 +174,9 @@ heuristics->record_requested_gc(); - if (ExplicitGCInvokesConcurrent) { + if (ShenandoahImplicitGCInvokesConcurrent) { policy->record_implicit_to_concurrent(); - mode = concurrent_normal; + mode = default_mode; // Unload and clean up everything heap->set_process_references(heuristics->can_process_references()); @@ -183,9 +187,9 @@ } } else { // Potential normal cycle: ask heuristics if it wants to act - if (heuristics->should_start_normal_gc()) { - mode = concurrent_normal; - cause = GCCause::_shenandoah_concurrent_gc; + if (heuristics->should_start_gc()) { + mode = default_mode; + cause = default_cause; } // Ask policy if this cycle wants to process references or unload classes @@ -219,6 +223,9 @@ switch (mode) { case none: break; + case concurrent_traversal: + service_concurrent_traversal_cycle(cause); + break; case concurrent_normal: service_concurrent_normal_cycle(cause); break; @@ -310,6 +317,30 @@ terminate(); } +void ShenandoahControlThread::service_concurrent_traversal_cycle(GCCause::Cause cause) { + ShenandoahGCSession session(cause); + + ShenandoahHeap* heap = ShenandoahHeap::heap(); + TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters()); + + // Reset for upcoming cycle + heap->entry_reset(); + + heap->vmop_entry_init_traversal(); + + if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_traversal)) return; + + heap->entry_traversal(); + if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_traversal)) return; + + heap->vmop_entry_final_traversal(); + + heap->entry_cleanup(); + + heap->heuristics()->record_success_concurrent(); + heap->shenandoah_policy()->record_success_concurrent(); +} + void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cause) { // Normal cycle goes via all concurrent phases. If allocation failure (af) happens during // any of the concurrent phases, it first degrades to Degenerated GC and completes GC there. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahControlThread.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -58,6 +58,7 @@ private: typedef enum { none, + concurrent_traversal, concurrent_normal, stw_degenerated, stw_full @@ -96,6 +97,7 @@ void service_concurrent_normal_cycle(GCCause::Cause cause); void service_stw_full_cycle(GCCause::Cause cause); void service_stw_degenerated_cycle(GCCause::Cause cause, ShenandoahHeap::ShenandoahDegenPoint point); + void service_concurrent_traversal_cycle(GCCause::Cause cause); void service_uncommit(double shrink_before); bool try_set_alloc_failure_gc(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_HPP + +#include "oops/oop.hpp" +#include "utilities/globalDefinitions.hpp" + +class ShenandoahForwarding { +public: + /* Gets forwardee from the given object. + */ + static inline oop get_forwardee(oop obj); + + /* Returns the raw value from forwardee slot. + */ + static inline HeapWord* get_forwardee_raw(oop obj); + + /* Returns the raw value from forwardee slot without any checks. + * Used for quick verification. + */ + static inline HeapWord* get_forwardee_raw_unchecked(oop obj); + + /** + * Returns true if the object is forwarded, false otherwise. + */ + static inline bool is_forwarded(oop obj); + + /* Tries to atomically update forwardee in $holder object to $update. + * Assumes $holder points at itself. + * Asserts $holder is in from-space. + * Asserts $update is in to-space. + * + * Returns the new object 'update' upon success, or + * the new forwardee that a competing thread installed. + */ + static inline oop try_update_forwardee(oop obj, oop update); + +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.inline.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahForwarding.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_INLINE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_INLINE_HPP + +#include "gc_implementation/shenandoah/shenandoahAsserts.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" +#include "runtime/atomic.hpp" + +inline HeapWord* ShenandoahForwarding::get_forwardee_raw(oop obj) { + shenandoah_assert_in_heap(NULL, obj); + return get_forwardee_raw_unchecked(obj); +} + +inline HeapWord* ShenandoahForwarding::get_forwardee_raw_unchecked(oop obj) { + markOop mark = obj->mark(); + if (mark->is_marked()) { + return (HeapWord*) mark->clear_lock_bits(); + } else { + return (HeapWord*) obj; + } +} + +inline oop ShenandoahForwarding::get_forwardee(oop obj) { + shenandoah_assert_correct(NULL, obj); + return oop(get_forwardee_raw_unchecked(obj)); +} + +inline bool ShenandoahForwarding::is_forwarded(oop obj) { + return obj->mark()->is_marked(); +} + +inline oop ShenandoahForwarding::try_update_forwardee(oop obj, oop update) { + markOop old_mark = obj->mark(); + if (old_mark->is_marked()) { + return (oop) old_mark->clear_lock_bits(); + } + + markOop new_mark = markOopDesc::encode_pointer_as_mark(update); + markOop prev_mark = obj->cas_set_mark(new_mark, old_mark); + if (prev_mark == old_mark) { + return update; + } else { + return (oop) prev_mark->clear_lock_bits(); + } +} + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_INLINE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahFreeSet.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahFreeSet.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahFreeSet.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahFreeSet.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,7 @@ #include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" ShenandoahFreeSet::ShenandoahFreeSet(ShenandoahHeap* heap,size_t max_regions) : _heap(heap), @@ -175,6 +176,15 @@ // Record actual allocation size req.set_actual_size(size); + + if (req.is_gc_alloc() && _heap->is_concurrent_traversal_in_progress()) { + // Traversal needs to traverse through GC allocs. Adjust TAMS to the new top + // so that these allocations appear below TAMS, and thus get traversed. + // See top of shenandoahTraversal.cpp for an explanation. + _heap->marking_context()->capture_top_at_mark_start(r); + _heap->traversal_gc()->traversal_set()->add_region_check_for_duplicates(r); + OrderAccess::fence(); + } } if (result == NULL || has_no_alloc_capacity(r)) { @@ -480,8 +490,12 @@ size_t max_humongous = max_contig * ShenandoahHeapRegion::region_size_bytes(); size_t free = capacity() - used(); - ls->print("Free: " SIZE_FORMAT "M (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "K, Max humongous: " SIZE_FORMAT "K, ", - total_free / M, mutator_count(), max / K, max_humongous / K); + ls->print("Free: " SIZE_FORMAT "%s (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "%s, Max humongous: " SIZE_FORMAT "%s, ", + byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), + mutator_count(), + byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), + byte_size_in_proper_unit(max_humongous), proper_unit_for_byte_size(max_humongous) + ); size_t frag_ext; if (free > 0) { @@ -514,8 +528,10 @@ } } - ls->print_cr("Evacuation Reserve: " SIZE_FORMAT "M (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "K", - total_free / M, collector_count(), max / K); + ls->print_cr("Evacuation Reserve: " SIZE_FORMAT "%s (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "%s", + byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), + collector_count(), + byte_size_in_proper_unit(max), proper_unit_for_byte_size(max)); } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -61,13 +61,18 @@ " *) static - start concurrent GC when static free heap " \ " threshold and static allocation threshold are " \ " tripped;" \ - " *) passive - do not start concurrent GC, wait for Full GC; " \ " *) aggressive - run concurrent GC continuously, evacuate " \ " everything;" \ " *) compact - run GC with lower footprint target, may end up " \ " doing continuous GC, evacuate lots of live " \ " objects, uncommit heap aggressively;") \ \ + product(ccstr, ShenandoahGCMode, "normal", \ + "The GC mode to use in Shenandoah GC. Possible values" \ + " *) normal - normal GC (mark-evac-update)" \ + " *) traversal - traversal GC (single-pass)" \ + " *) passive - disable concurrent GC, do stop-the-world GC") \ + \ experimental(ccstr, ShenandoahUpdateRefsEarly, "adaptive", \ "Run a separate concurrent reference updating phase after" \ "concurrent evacuation. Possible values: 'on', 'off', 'adaptive'")\ @@ -230,7 +235,7 @@ "Time is in microseconds.") \ \ experimental(uintx, ShenandoahEvacAssist, 10, \ - "How many objects to evacuate on WB assist path. " \ + "How many objects to evacuate on LRB assist path. " \ "Use zero to disable.") \ \ experimental(bool, ShenandoahPacing, true, \ @@ -276,11 +281,11 @@ "Should internally-caused GCs invoke concurrent cycles, or go to" \ "stop-the-world (degenerated/full)?") \ \ - experimental(bool, ShenandoahHumongousMoves, true, \ + diagnostic(bool, ShenandoahHumongousMoves, true, \ "Allow moving humongous regions. This makes GC more resistant " \ "to external fragmentation that may otherwise fail other " \ "humongous allocations, at the expense of higher GC copying " \ - "costs.") \ + "costs. Currently affects stop-the-world (full) cycle only.") \ \ diagnostic(bool, ShenandoahOOMDuringEvacALot, false, \ "Simulate OOM during evacuation frequently.") \ @@ -291,9 +296,6 @@ diagnostic(bool, ShenandoahTerminationTrace, false, \ "Tracing task termination timings") \ \ - develop(bool, ShenandoahVerifyObjectEquals, false, \ - "Verify that == and != are not used on oops. Only in fastdebug") \ - \ diagnostic(bool, ShenandoahAlwaysPreTouch, false, \ "Pre-touch heap memory, overrides global AlwaysPreTouch") \ \ @@ -323,24 +325,20 @@ diagnostic(bool, ShenandoahSATBBarrier, true, \ "Turn on/off SATB barriers in Shenandoah") \ \ - diagnostic(bool, ShenandoahWriteBarrier, true, \ - "Turn on/off write barriers in Shenandoah") \ + diagnostic(bool, ShenandoahKeepAliveBarrier, true, \ + "Turn on/off keep alive barriers in Shenandoah") \ \ - diagnostic(bool, ShenandoahReadBarrier, true, \ - "Turn on/off read barriers in Shenandoah") \ + diagnostic(bool, ShenandoahStoreValEnqueueBarrier, false, \ + "Turn on/off enqueuing of oops for storeval barriers") \ \ diagnostic(bool, ShenandoahCASBarrier, true, \ "Turn on/off CAS barriers in Shenandoah") \ \ - diagnostic(bool, ShenandoahAcmpBarrier, true, \ - "Turn on/off acmp barriers in Shenandoah") \ - \ diagnostic(bool, ShenandoahCloneBarrier, true, \ "Turn on/off clone barriers in Shenandoah") \ \ - diagnostic(bool, ShenandoahStoreCheck, false, \ - "Emit additional code that checks objects are written to only" \ - " in to-space") \ + diagnostic(bool, ShenandoahLoadRefBarrier, true, \ + "Turn on/off load-reference barriers in Shenandoah") \ \ experimental(bool, ShenandoahConcurrentScanCodeRoots, true, \ "Scan code roots concurrently, instead of during a pause") \ @@ -351,24 +349,13 @@ " 1 - parallel iterator;" \ " 2 - parallel iterator with cset filters;") \ \ - experimental(bool, ShenandoahOptimizeStaticFinals, true, \ + diagnostic(bool, ShenandoahOptimizeStaticFinals, true, \ "Optimize barriers on static final fields. " \ "Turn it off for maximum compatibility with reflection or JNI " \ "code that manipulates final fields.") \ \ - experimental(bool, ShenandoahOptimizeInstanceFinals, false, \ - "Optimize barriers on final instance fields." \ - "Turn it off for maximum compatibility with reflection or JNI " \ - "code that manipulates final fields.") \ - \ - experimental(bool, ShenandoahOptimizeStableFinals, false, \ - "Optimize barriers on stable fields." \ - "Turn it off for maximum compatibility with reflection or JNI " \ - "code that manipulates final fields.") \ - \ - experimental(bool, ShenandoahDontIncreaseWBFreq, true, \ - "Common 2 WriteBarriers or WriteBarrier and a ReadBarrier only " \ - "if the resulting WriteBarrier isn't executed more frequently") \ + experimental(bool, ShenandoahCommonGCStateLoads, false, \ + "Enable commonming for GC state loads in generated code.") \ \ develop(bool, ShenandoahVerifyOptoBarriers, false, \ "Verify no missing barriers in c2") \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,7 +28,6 @@ #include "gc_implementation/shenandoah/shenandoahGCTraceTime.hpp" #include "gc_implementation/shared/parallelCleaning.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahAllocTracker.hpp" #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" #include "gc_implementation/shenandoah/shenandoahClosures.inline.hpp" @@ -41,25 +40,24 @@ #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegionSet.hpp" +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" #include "gc_implementation/shenandoah/shenandoahMarkCompact.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc_implementation/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc_implementation/shenandoah/shenandoahMetrics.hpp" +#include "gc_implementation/shenandoah/shenandoahNormalMode.hpp" #include "gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc_implementation/shenandoah/shenandoahPacer.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahPassiveMode.hpp" #include "gc_implementation/shenandoah/shenandoahRootProcessor.hpp" #include "gc_implementation/shenandoah/shenandoahTaskqueue.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalMode.hpp" #include "gc_implementation/shenandoah/shenandoahUtils.hpp" #include "gc_implementation/shenandoah/shenandoahVerifier.hpp" #include "gc_implementation/shenandoah/shenandoahCodeRoots.hpp" #include "gc_implementation/shenandoah/shenandoahVMOperations.hpp" #include "gc_implementation/shenandoah/shenandoahWorkGroup.hpp" #include "gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp" -#include "gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" -#include "gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" -#include "gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" -#include "gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" -#include "gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "memory/metaspace.hpp" #include "runtime/vmThread.hpp" @@ -127,8 +125,6 @@ jint ShenandoahHeap::initialize() { CollectedHeap::pre_initialize(); - ShenandoahBrooksPointer::initial_checks(); - initialize_heuristics(); // @@ -362,6 +358,10 @@ _pacer = NULL; } + _traversal_gc = strcmp(ShenandoahGCMode, "traversal") == 0 ? + new ShenandoahTraversalGC(this, _num_regions) : + NULL; + _control_thread = new ShenandoahControlThread(); log_info(gc, init)("Initialize Shenandoah heap: " SIZE_FORMAT "%s initial, " SIZE_FORMAT "%s min, " SIZE_FORMAT "%s max", @@ -379,36 +379,34 @@ #endif void ShenandoahHeap::initialize_heuristics() { - if (ShenandoahGCHeuristics != NULL) { - if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - _heuristics = new ShenandoahAggressiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - _heuristics = new ShenandoahStaticHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - _heuristics = new ShenandoahAdaptiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "passive") == 0) { - _heuristics = new ShenandoahPassiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - _heuristics = new ShenandoahCompactHeuristics(); + if (ShenandoahGCMode != NULL) { + if (strcmp(ShenandoahGCMode, "traversal") == 0) { + _gc_mode = new ShenandoahTraversalMode(); + } else if (strcmp(ShenandoahGCMode, "normal") == 0) { + _gc_mode = new ShenandoahNormalMode(); + } else if (strcmp(ShenandoahGCMode, "passive") == 0) { + _gc_mode = new ShenandoahPassiveMode(); } else { - vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); - } - - if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) { - vm_exit_during_initialization( - err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.", - _heuristics->name())); - } - if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) { - vm_exit_during_initialization( - err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.", - _heuristics->name())); + vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option"); } - log_info(gc, init)("Shenandoah heuristics: %s", - _heuristics->name()); } else { ShouldNotReachHere(); } + _gc_mode->initialize_flags(); + _heuristics = _gc_mode->initialize_heuristics(); + + if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) { + vm_exit_during_initialization( + err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.", + _heuristics->name())); + } + if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) { + vm_exit_during_initialization( + err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.", + _heuristics->name())); + } + log_info(gc, init)("Shenandoah heuristics: %s", + _heuristics->name()); } ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : @@ -418,6 +416,7 @@ _regions(NULL), _free_set(NULL), _collection_set(NULL), + _traversal_gc(NULL), _update_refs_iterator(this), _bytes_allocated_since_gc_start(0), _max_workers((uint)MAX2(ConcGCThreads, ParallelGCThreads)), @@ -440,10 +439,14 @@ log_info(gc, init)("Reference processing: %s", ParallelRefProcEnabled ? "parallel" : "serial"); _scm = new ShenandoahConcurrentMark(); + _full_gc = new ShenandoahMarkCompact(); _used = 0; _max_workers = MAX2(_max_workers, 1U); + + // SharedHeap did not initialize this for us, and we want our own workgang anyway. + assert(SharedHeap::_workers == NULL && _workers == NULL, "Should not be initialized yet"); _workers = new ShenandoahWorkGang("Shenandoah GC Threads", _max_workers, /* are_GC_task_threads */true, /* are_ConcurrentGC_threads */false); @@ -452,6 +455,7 @@ } else { _workers->initialize_workers(); } + assert(SharedHeap::_workers == _workers, "Sanity: initialized the correct field"); } #ifdef _MSC_VER @@ -489,16 +493,21 @@ void ShenandoahHeap::print_on(outputStream* st) const { st->print_cr("Shenandoah Heap"); - st->print_cr(" " SIZE_FORMAT "K total, " SIZE_FORMAT "K committed, " SIZE_FORMAT "K used", - max_capacity() / K, committed() / K, used() / K); - st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"K regions", - num_regions(), ShenandoahHeapRegion::region_size_bytes() / K); + st->print_cr(" " SIZE_FORMAT "%s total, " SIZE_FORMAT "%s committed, " SIZE_FORMAT "%s used", + byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()), + byte_size_in_proper_unit(committed()), proper_unit_for_byte_size(committed()), + byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); + st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"%s regions", + num_regions(), + byte_size_in_proper_unit(ShenandoahHeapRegion::region_size_bytes()), + proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes())); st->print("Status: "); if (has_forwarded_objects()) st->print("has forwarded objects, "); if (is_concurrent_mark_in_progress()) st->print("marking, "); if (is_evacuation_in_progress()) st->print("evacuating, "); if (is_update_refs_in_progress()) st->print("updating refs, "); + if (is_concurrent_traversal_in_progress()) st->print("traversal, "); if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); if (is_full_gc_in_progress()) st->print("full gc, "); if (is_full_gc_move_in_progress()) st->print("full gc move, "); @@ -825,12 +834,9 @@ HeapWord* ShenandoahHeap::mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) { - ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared(size + ShenandoahBrooksPointer::word_size()); - HeapWord* filler = allocate_memory(req); - HeapWord* result = filler + ShenandoahBrooksPointer::word_size(); - if (filler != NULL) { - ShenandoahBrooksPointer::initialize(oop(result)); - + ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared(size); + HeapWord* result = allocate_memory(req); + if (result != NULL) { assert(! in_collection_set(result), "never allocate in targetted region"); return result; } else { @@ -848,9 +854,8 @@ void do_object(oop p) { shenandoah_assert_marked(NULL, p); - if (oopDesc::unsafe_equals(p, ShenandoahBarrierSet::resolve_forwarded_not_null(p))) { - bool evac; - _heap->evacuate_object(p, _thread, evac); + if (!p->is_forwarded()) { + _heap->evacuate_object(p, _thread); } } }; @@ -886,7 +891,7 @@ ShenandoahConcurrentEvacuateRegionObjectClosure cl(_sh); ShenandoahHeapRegion* r; while ((r =_cs->claim_next()) != NULL) { - assert(r->has_live(), "all-garbage regions are reclaimed early"); + assert(r->has_live(), err_msg("Region " SIZE_FORMAT " should have been reclaimed early", r->region_number())); _sh->marked_object_iterate(r, &cl); if (ShenandoahPacing) { @@ -926,8 +931,8 @@ void ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) { assert(start->is_humongous_start(), "reclaim regions starting with the first one"); - oop humongous_obj = oop(start->bottom() + ShenandoahBrooksPointer::word_size()); - size_t size = humongous_obj->size() + ShenandoahBrooksPointer::word_size(); + oop humongous_obj = oop(start->bottom()); + size_t size = humongous_obj->size(); size_t required_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize); size_t index = start->region_number() + required_regions - 1; @@ -999,16 +1004,6 @@ COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); } -void ShenandoahHeap::roots_iterate(OopClosure* cl) { - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); - - CodeBlobToOopClosure blobsCl(cl, false); - CLDToOopClosure cldCl(cl); - - ShenandoahRootProcessor rp(this, 1, ShenandoahPhaseTimings::_num_phases); - rp.process_all_roots(cl, NULL, &cldCl, &blobsCl, NULL, 0); -} - size_t ShenandoahHeap::unsafe_max_tlab_alloc(Thread *thread) const { // Returns size in bytes return MIN2(_free_set->unsafe_peek_free(), ShenandoahHeapRegion::max_tlab_size_bytes()); @@ -1169,7 +1164,22 @@ T o = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(o)) { oop obj = oopDesc::decode_heap_oop_not_null(o); - obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj); + if (fwd == NULL) { + // There is an odd interaction with VM_HeapWalkOperation, see jvmtiTagMap.cpp. + // + // That operation walks the reachable objects on its own, storing the marking + // wavefront in the object marks. When it is done, it calls the CollectedHeap + // to iterate over all objects to clean up the mess. When it reaches here, + // the Shenandoah fwdptr resolution code encounters the marked objects with + // NULL forwardee. Trying to act on that would crash the VM. Or fail the + // asserts, should we go for resolve_forwarded_pointer(obj). + // + // Therefore, we have to dodge it by doing the raw access to forwardee, and + // assuming the object had no forwardee, if that thing is NULL. + } else { + obj = fwd; + } assert(obj->is_oop(), "must be a valid oop"); if (!_bitmap->isMarked((HeapWord*) obj)) { _bitmap->mark((HeapWord*) obj); @@ -1226,7 +1236,7 @@ ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); CLDToOopClosure clds(&oops, false); CodeBlobToOopClosure blobs(&oops, false); - rp.process_all_roots(&oops, &oops, &clds, &blobs, NULL, 0); + rp.process_all_roots(&oops, &clds, &blobs, NULL, 0); // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { @@ -1446,30 +1456,43 @@ stop_concurrent_marking(); + // All allocations past TAMS are implicitly live, adjust the region data. + // Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap. { ShenandoahGCPhase phase(ShenandoahPhaseTimings::complete_liveness); - - // All allocations past TAMS are implicitly live, adjust the region data. - // Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap. ShenandoahCompleteLivenessClosure cl; parallel_heap_region_iterate(&cl); } + // Force the threads to reacquire their TLABs outside the collection set. { - ShenandoahGCPhase prepare_evac(ShenandoahPhaseTimings::prepare_evac); - + ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs); make_parsable(true); + } + // We are about to select the collection set, make sure it knows about + // current pinning status. Also, this allows trashing more regions that + // now have their pinning status dropped. + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::sync_pinned); + sync_pinned_region_status(); + } + + // Trash the collection set left over from previous cycle, if any. + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset); trash_cset_regions(); + } - { - ShenandoahHeapLocker locker(lock()); - _collection_set->clear(); - _free_set->clear(); + { + ShenandoahGCPhase prepare_evac(ShenandoahPhaseTimings::prepare_evac); - heuristics()->choose_collection_set(_collection_set); - _free_set->rebuild(); - } + ShenandoahHeapLocker locker(lock()); + _collection_set->clear(); + _free_set->clear(); + + heuristics()->choose_collection_set(_collection_set); + _free_set->rebuild(); } // If collection set has candidates, start evacuation. @@ -1557,6 +1580,18 @@ concurrent_mark()->preclean_weak_refs(); } +void ShenandoahHeap::op_init_traversal() { + traversal_gc()->init_traversal_collection(); +} + +void ShenandoahHeap::op_traversal() { + traversal_gc()->concurrent_traversal_collection(); +} + +void ShenandoahHeap::op_final_traversal() { + traversal_gc()->final_traversal_collection(); +} + void ShenandoahHeap::op_full(GCCause::Cause cause) { ShenandoahMetricsSnapshot metrics; metrics.snap_before(); @@ -1564,9 +1599,8 @@ full_gc()->do_it(cause); metrics.snap_after(); - metrics.print(); - if (metrics.is_good_progress("Full GC")) { + if (metrics.is_good_progress()) { _progress_last_gc.set(); } else { // Nothing to do. Tell the allocation path that we have failed to make @@ -1586,6 +1620,24 @@ metrics.snap_before(); switch (point) { + case _degenerated_traversal: + { + // Drop the collection set. Note: this leaves some already forwarded objects + // behind, which may be problematic, see comments for ShenandoahEvacAssist + // workarounds in ShenandoahTraversalHeuristics. + + ShenandoahHeapLocker locker(lock()); + collection_set()->clear_current_index(); + for (size_t i = 0; i < collection_set()->count(); i++) { + ShenandoahHeapRegion* r = collection_set()->next(); + r->make_regular_bypass(); + } + collection_set()->clear(); + } + op_final_traversal(); + op_cleanup(); + return; + // The cases below form the Duff's-like device: it describes the actual GC cycle, // but enters it at different points, depending on which concurrent phase had // degenerated. @@ -1602,6 +1654,13 @@ set_process_references(heuristics()->can_process_references()); set_unload_classes(heuristics()->can_unload_classes()); + if (is_traversal_mode()) { + // Not possible to degenerate from here, upgrade to Full GC right away. + cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); + op_degenerated_fail(); + return; + } + op_reset(); op_init_mark(); @@ -1630,7 +1689,29 @@ // it would be a simple check, which is supposed to be fast. This is also // safe to do even without degeneration, as CSet iterator is at beginning // in preparation for evacuation anyway. - collection_set()->clear_current_index(); + // + // Before doing that, we need to make sure we never had any cset-pinned + // regions. This may happen if allocation failure happened when evacuating + // the about-to-be-pinned object, oom-evac protocol left the object in + // the collection set, and then the pin reached the cset region. If we continue + // the cycle here, we would trash the cset and alive objects in it. To avoid + // it, we fail degeneration right away and slide into Full GC to recover. + + { + sync_pinned_region_status(); + collection_set()->clear_current_index(); + + ShenandoahHeapRegion* r; + while ((r = collection_set()->next()) != NULL) { + if (r->is_pinned()) { + cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); + op_degenerated_fail(); + return; + } + } + + collection_set()->clear_current_index(); + } op_stw_evac(); if (cancelled_gc()) { @@ -1674,11 +1755,10 @@ } metrics.snap_after(); - metrics.print(); // Check for futility and fail. There is no reason to do several back-to-back Degenerated cycles, // because that probably means the heap is overloaded and/or fragmented. - if (!metrics.is_good_progress("Degenerated GC")) { + if (!metrics.is_good_progress()) { _progress_last_gc.unset(); cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); op_degenerated_futile(); @@ -1710,7 +1790,7 @@ } void ShenandoahHeap::force_satb_flush_all_threads() { - if (!is_concurrent_mark_in_progress()) { + if (!is_concurrent_mark_in_progress() && !is_concurrent_traversal_in_progress()) { // No need to flush SATBs return; } @@ -1744,22 +1824,16 @@ JavaThread::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress); } +void ShenandoahHeap::set_concurrent_traversal_in_progress(bool in_progress) { + set_gc_state_mask(TRAVERSAL | HAS_FORWARDED | UPDATEREFS, in_progress); + JavaThread::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress); +} + void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint"); set_gc_state_mask(EVACUATION, in_progress); } -HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) { - // Initialize Brooks pointer for the next object - HeapWord* result = obj + ShenandoahBrooksPointer::word_size(); - ShenandoahBrooksPointer::initialize(oop(result)); - return result; -} - -uint ShenandoahHeap::oop_extra_words() { - return ShenandoahBrooksPointer::word_size(); -} - void ShenandoahHeap::ref_processing_init() { MemRegion mr = reserved_region(); @@ -1949,18 +2023,45 @@ } oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) { - o = barrier_set()->write_barrier(o); - ShenandoahHeapLocker locker(lock()); - heap_region_containing(o)->make_pinned(); + heap_region_containing(o)->record_pin(); return o; } void ShenandoahHeap::unpin_object(JavaThread* thr, oop o) { - o = barrier_set()->read_barrier(o); + heap_region_containing(o)->record_unpin(); +} + +void ShenandoahHeap::sync_pinned_region_status() { ShenandoahHeapLocker locker(lock()); - heap_region_containing(o)->make_unpinned(); + + for (size_t i = 0; i < num_regions(); i++) { + ShenandoahHeapRegion *r = get_region(i); + if (r->is_active()) { + if (r->is_pinned()) { + if (r->pin_count() == 0) { + r->make_unpinned(); + } + } else { + if (r->pin_count() > 0) { + r->make_pinned(); + } + } + } + } + + assert_pinned_region_status(); } +#ifdef ASSERT +void ShenandoahHeap::assert_pinned_region_status() { + for (size_t i = 0; i < num_regions(); i++) { + ShenandoahHeapRegion* r = get_region(i); + assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0), + err_msg("Region " SIZE_FORMAT " pinning status is inconsistent", i)); + } +} +#endif + GCTimer* ShenandoahHeap::gc_timer() const { return _gc_timer; } @@ -2049,14 +2150,19 @@ } set_update_refs_in_progress(true); - make_parsable(true); - for (uint i = 0; i < num_regions(); i++) { - ShenandoahHeapRegion* r = get_region(i); - r->set_concurrent_iteration_safe_limit(r->top()); - } - // Reset iterator. - _update_refs_iterator.reset(); + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_prepare); + + make_parsable(true); + for (uint i = 0; i < num_regions(); i++) { + ShenandoahHeapRegion* r = get_region(i); + r->set_concurrent_iteration_safe_limit(r->top()); + } + + // Reset iterator. + _update_refs_iterator.reset(); + } if (ShenandoahPacing) { pacer()->setup_for_updaterefs(); @@ -2068,7 +2174,7 @@ // Check if there is left-over work, and finish it if (_update_refs_iterator.has_next()) { - ShenandoahGCPhase final_work(ShenandoahPhaseTimings::final_update_refs_finish_work); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work); // Finish updating references where we left off. clear_cancelled_gc(); @@ -2086,9 +2192,11 @@ ShenandoahPhaseTimings::degen_gc_update_roots: ShenandoahPhaseTimings::final_update_refs_roots); - ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset); + trash_cset_regions(); + } - trash_cset_regions(); set_has_forwarded_objects(false); set_update_refs_in_progress(false); @@ -2100,6 +2208,13 @@ Universe::verify(); } + // Drop unnecessary "pinned" state from regions that does not have CP marks + // anymore, as this would allow trashing them below. + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_sync_pinned); + sync_pinned_region_status(); + } + { ShenandoahHeapLocker locker(lock()); _free_set->rebuild(); @@ -2237,6 +2352,26 @@ VMThread::execute(&op); } +void ShenandoahHeap::vmop_entry_init_traversal() { + TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); + ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_traversal_gc_gross); + + try_inject_alloc_failure(); + VM_ShenandoahInitTraversalGC op; + VMThread::execute(&op); +} + +void ShenandoahHeap::vmop_entry_final_traversal() { + TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); + ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_traversal_gc_gross); + + try_inject_alloc_failure(); + VM_ShenandoahFinalTraversalGC op; + VMThread::execute(&op); +} + void ShenandoahHeap::vmop_entry_full(GCCause::Cause cause) { TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters()); ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); @@ -2325,6 +2460,36 @@ op_final_updaterefs(); } +void ShenandoahHeap::entry_init_traversal() { + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_traversal_gc); + + static const char* msg = "Pause Init Traversal"; + GCTraceTime time(msg, PrintGC, _gc_timer, tracer()->gc_id()); + EventMark em("%s", msg); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_stw_traversal(), + "init traversal"); + + op_init_traversal(); +} + +void ShenandoahHeap::entry_final_traversal() { + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_traversal_gc); + + static const char* msg = "Pause Final Traversal"; + GCTraceTime time(msg, PrintGC, _gc_timer, tracer()->gc_id()); + EventMark em("%s", msg); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_stw_traversal(), + "final traversal"); + + op_final_traversal(); +} + void ShenandoahHeap::entry_full(GCCause::Cause cause) { ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc); @@ -2450,6 +2615,21 @@ } } +void ShenandoahHeap::entry_traversal() { + static const char* msg = "Concurrent traversal"; + GCTraceTime time(msg, PrintGC, NULL, tracer()->gc_id(), true); + EventMark em("%s", msg); + + TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters()); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_conc_traversal(), + "concurrent traversal"); + + try_inject_alloc_failure(); + op_traversal(); +} + void ShenandoahHeap::entry_uncommit(double shrink_before) { static const char *msg = "Concurrent uncommit"; GCTraceTime time(msg, PrintGC, NULL, tracer()->gc_id(), true); @@ -2578,6 +2758,8 @@ switch (point) { case _degenerated_unset: return "Pause Degenerated GC ()"; + case _degenerated_traversal: + return "Pause Degenerated GC (Traversal)"; case _degenerated_outside_cycle: return "Pause Degenerated GC (Outside of Cycle)"; case _degenerated_mark: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,7 +27,7 @@ #include "gc_implementation/shared/markBitMap.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" #include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapLock.hpp" +#include "gc_implementation/shenandoah/shenandoahLock.hpp" #include "gc_implementation/shenandoah/shenandoahEvacOOMHandler.hpp" #include "gc_implementation/shenandoah/shenandoahSharedVariables.hpp" @@ -46,8 +46,10 @@ class ShenandoahMonitoringSupport; class ShenandoahHeuristics; class ShenandoahMarkingContext; +class ShenandoahMode; class ShenandoahPhaseTimings; class ShenandoahPacer; +class ShenandoahTraversalGC; class ShenandoahVerifier; class ShenandoahWorkGang; class VMStructs; @@ -97,6 +99,9 @@ }; #endif +typedef ShenandoahLock ShenandoahHeapLock; +typedef ShenandoahLocker ShenandoahHeapLocker; + // Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers // to encode forwarding data. See BrooksPointer for details on forwarding data encoding. // See ShenandoahControlThread for GC cycle structure. @@ -180,7 +185,6 @@ // private: uint _max_workers; - ShenandoahWorkGang* _workers; public: uint max_workers(); @@ -232,7 +236,10 @@ EVACUATION_BITPOS = 2, // Heap is under updating: needs SVRB/SVWB barriers. - UPDATEREFS_BITPOS = 3 + UPDATEREFS_BITPOS = 3, + + // Heap is under traversal collection + TRAVERSAL_BITPOS = 4 }; enum GCState { @@ -240,7 +247,8 @@ HAS_FORWARDED = 1 << HAS_FORWARDED_BITPOS, MARKING = 1 << MARKING_BITPOS, EVACUATION = 1 << EVACUATION_BITPOS, - UPDATEREFS = 1 << UPDATEREFS_BITPOS + UPDATEREFS = 1 << UPDATEREFS_BITPOS, + TRAVERSAL = 1 << TRAVERSAL_BITPOS }; private: @@ -262,6 +270,7 @@ void set_degenerated_gc_in_progress(bool in_progress); void set_full_gc_in_progress(bool in_progress); void set_full_gc_move_in_progress(bool in_progress); + void set_concurrent_traversal_in_progress(bool in_progress); void set_has_forwarded_objects(bool cond); inline bool is_stable() const; @@ -272,6 +281,7 @@ inline bool is_degenerated_gc_in_progress() const; inline bool is_full_gc_in_progress() const; inline bool is_full_gc_move_in_progress() const; + inline bool is_concurrent_traversal_in_progress() const; inline bool has_forwarded_objects() const; inline bool is_gc_in_progress_mask(uint mask) const; @@ -282,6 +292,7 @@ public: enum ShenandoahDegenPoint { _degenerated_unset, + _degenerated_traversal, _degenerated_outside_cycle, _degenerated_mark, _degenerated_evac, @@ -293,6 +304,8 @@ switch (point) { case _degenerated_unset: return ""; + case _degenerated_traversal: + return "Traversal"; case _degenerated_outside_cycle: return "Outside of Cycle"; case _degenerated_mark: @@ -330,6 +343,8 @@ void vmop_entry_final_evac(); void vmop_entry_init_updaterefs(); void vmop_entry_final_updaterefs(); + void vmop_entry_init_traversal(); + void vmop_entry_final_traversal(); void vmop_entry_full(GCCause::Cause cause); void vmop_degenerated(ShenandoahDegenPoint point); @@ -340,6 +355,8 @@ void entry_final_evac(); void entry_init_updaterefs(); void entry_final_updaterefs(); + void entry_init_traversal(); + void entry_final_traversal(); void entry_full(GCCause::Cause cause); void entry_degenerated(int point); @@ -351,6 +368,7 @@ void entry_cleanup(); void entry_evac(); void entry_updaterefs(); + void entry_traversal(); void entry_uncommit(double shrink_before); private: @@ -360,6 +378,8 @@ void op_final_evac(); void op_init_updaterefs(); void op_final_updaterefs(); + void op_init_traversal(); + void op_final_traversal(); void op_full(GCCause::Cause cause); void op_degenerated(ShenandoahDegenPoint point); void op_degenerated_fail(); @@ -372,6 +392,7 @@ void op_conc_evac(); void op_stw_evac(); void op_updaterefs(); + void op_traversal(); void op_uncommit(double shrink_before); // Messages for GC trace event, they have to be immortal for @@ -386,9 +407,11 @@ private: ShenandoahControlThread* _control_thread; ShenandoahCollectorPolicy* _shenandoah_policy; + ShenandoahMode* _gc_mode; ShenandoahHeuristics* _heuristics; ShenandoahFreeSet* _free_set; ShenandoahConcurrentMark* _scm; + ShenandoahTraversalGC* _traversal_gc; ShenandoahMarkCompact* _full_gc; ShenandoahPacer* _pacer; ShenandoahVerifier* _verifier; @@ -404,6 +427,8 @@ ShenandoahHeuristics* heuristics() const { return _heuristics; } ShenandoahFreeSet* free_set() const { return _free_set; } ShenandoahConcurrentMark* concurrent_mark() { return _scm; } + ShenandoahTraversalGC* traversal_gc() const { return _traversal_gc; } + bool is_traversal_mode() const { return _traversal_gc != NULL; } ShenandoahPacer* pacer() const { return _pacer; } ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; } @@ -511,6 +536,9 @@ oop pin_object(JavaThread* thread, oop obj); void unpin_object(JavaThread* thread, oop obj); + void sync_pinned_region_status(); + void assert_pinned_region_status() NOT_DEBUG_RETURN; + // ---------- Allocation support // private: @@ -520,15 +548,9 @@ HeapWord* allocate_new_gclab(size_t min_size, size_t word_size, size_t* actual_size); public: -#ifndef CC_INTERP - void compile_prepare_oop(MacroAssembler* masm, Register obj); -#endif - HeapWord* allocate_memory(ShenandoahAllocRequest& request); HeapWord* mem_allocate(size_t size, bool* what); - uint oop_extra_words(); - void notify_mutator_alloc_words(size_t words, bool waste); // Shenandoah supports TLAB allocation @@ -540,8 +562,6 @@ size_t max_tlab_size() const; size_t tlab_used(Thread* ignored) const; - HeapWord* tlab_post_allocation_setup(HeapWord* obj); - void resize_tlabs(); void resize_all_tlabs(); @@ -628,7 +648,7 @@ // Evacuates object src. Returns the evacuated object, either evacuated // by this thread, or by some other thread. - inline oop evacuate_object(oop src, Thread* thread, bool& evacuated); + inline oop evacuate_object(oop src, Thread* thread); // Call before/after evacuation. void enter_evacuation(); @@ -638,6 +658,9 @@ // public: template + inline oop evac_update_with_forwarded(T* p); + + template inline oop maybe_update_with_forwarded(T* p); template @@ -646,15 +669,13 @@ template inline oop update_with_forwarded_not_null(T* p, oop obj); - inline oop atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c); - inline oop atomic_compare_exchange_oop(oop n, oop* addr, oop c); + static inline oop cas_oop(oop n, narrowOop* addr, oop c); + static inline oop cas_oop(oop n, oop* addr, oop c); void trash_humongous_region_at(ShenandoahHeapRegion *r); void stop_concurrent_marking(); - void roots_iterate(OopClosure* cl); - private: void trash_cset_regions(); void update_heap_references(bool concurrent); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,11 +26,11 @@ #include "gc_implementation/shared/markBitMap.inline.hpp" #include "memory/threadLocalAllocBuffer.inline.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.inline.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" #include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" #include "gc_implementation/shenandoah/shenandoahCollectionSet.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.inline.hpp" #include "gc_implementation/shenandoah/shenandoahControlThread.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.hpp" @@ -55,7 +55,7 @@ } inline ShenandoahWorkGang* ShenandoahHeap::workers() const { - return _workers; + return (ShenandoahWorkGang*)_workers; } inline size_t ShenandoahHeap::heap_region_index_containing(const void* addr) const { @@ -98,11 +98,36 @@ } } -inline oop ShenandoahHeap::atomic_compare_exchange_oop(oop n, oop* addr, oop c) { +template +inline oop ShenandoahHeap::evac_update_with_forwarded(T* p) { + T o = oopDesc::load_heap_oop(p); + if (!oopDesc::is_null(o)) { + oop heap_oop = oopDesc::decode_heap_oop_not_null(o); + if (in_collection_set(heap_oop)) { + oop forwarded_oop = ShenandoahBarrierSet::resolve_forwarded_not_null(heap_oop); + if (forwarded_oop == heap_oop) { + forwarded_oop = evacuate_object(heap_oop, Thread::current()); + } + oop prev = cas_oop(forwarded_oop, p, heap_oop); + if (prev == heap_oop) { + return forwarded_oop; + } else { + return NULL; + } + } + return heap_oop; + } else { + return NULL; + } +} + +inline oop ShenandoahHeap::cas_oop(oop n, oop* addr, oop c) { + assert(is_ptr_aligned(addr, sizeof(narrowOop)), err_msg("Address should be aligned: " PTR_FORMAT, p2i(addr))); return (oop) Atomic::cmpxchg_ptr(n, addr, c); } -inline oop ShenandoahHeap::atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c) { +inline oop ShenandoahHeap::cas_oop(oop n, narrowOop* addr, oop c) { + assert(is_ptr_aligned(addr, sizeof(narrowOop)), err_msg("Address should be aligned: " PTR_FORMAT, p2i(addr))); narrowOop cmp = oopDesc::encode_heap_oop(c); narrowOop val = oopDesc::encode_heap_oop(n); return oopDesc::decode_heap_oop((narrowOop) Atomic::cmpxchg(val, addr, cmp)); @@ -117,24 +142,29 @@ oop forwarded_oop = ShenandoahBarrierSet::resolve_forwarded_not_null(heap_oop); shenandoah_assert_forwarded_except(p, heap_oop, is_full_gc_in_progress() || is_degenerated_gc_in_progress()); + shenandoah_assert_not_forwarded(p, forwarded_oop); shenandoah_assert_not_in_cset_except(p, forwarded_oop, cancelled_gc()); // If this fails, another thread wrote to p before us, it will be logged in SATB and the // reference be updated later. - oop result = atomic_compare_exchange_oop(forwarded_oop, p, heap_oop); + oop witness = cas_oop(forwarded_oop, p, heap_oop); - if (oopDesc::unsafe_equals(result, heap_oop)) { // CAS successful. - return forwarded_oop; + if (witness != heap_oop) { + // CAS failed, someone had beat us to it. Normally, we would return the failure witness, + // because that would be the proper write of to-space object, enforced by strong barriers. + // However, there is a corner case with arraycopy. It can happen that a Java thread + // beats us with an arraycopy, which first copies the array, which potentially contains + // from-space refs, and only afterwards updates all from-space refs to to-space refs, + // which leaves a short window where the new array elements can be from-space. + // In this case, we can just resolve the result again. As we resolve, we need to consider + // the contended write might have been NULL. + oop result = ShenandoahBarrierSet::resolve_forwarded(witness); + shenandoah_assert_not_forwarded_except(p, result, (result == NULL)); + shenandoah_assert_not_in_cset_except(p, result, (result == NULL) || cancelled_gc()); + return result; } else { - // Note: we used to assert the following here. This doesn't work because sometimes, during - // marking/updating-refs, it can happen that a Java thread beats us with an arraycopy, - // which first copies the array, which potentially contains from-space refs, and only afterwards - // updates all from-space refs to to-space refs, which leaves a short window where the new array - // elements can be from-space. - // assert(oopDesc::is_null(result) || - // oopDesc::unsafe_equals(result, ShenandoahBarrierSet::resolve_oop_static_not_null(result)), - // "expect not forwarded"); - return NULL; + // Success! We have updated with known to-space copy. We have already asserted it is sane. + return forwarded_oop; } } else { shenandoah_assert_not_forwarded(p, heap_oop); @@ -172,9 +202,7 @@ return allocate_from_gclab_slow(thread, size); } -inline oop ShenandoahHeap::evacuate_object(oop p, Thread* thread, bool& evacuated) { - evacuated = false; - +inline oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) { if (Thread::current()->is_oom_during_evac()) { // This thread went through the OOM during evac protocol and it is safe to return // the forward pointer. It must not attempt to evacuate any more. @@ -183,53 +211,47 @@ assert(thread->is_evac_allowed(), "must be enclosed in in oom-evac scope"); - size_t size_no_fwdptr = (size_t) p->size(); - size_t size_with_fwdptr = size_no_fwdptr + ShenandoahBrooksPointer::word_size(); + size_t size = p->size(); assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects"); bool alloc_from_gclab = true; - HeapWord* filler = NULL; + HeapWord* copy = NULL; #ifdef ASSERT if (ShenandoahOOMDuringEvacALot && (os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call - filler = NULL; + copy = NULL; } else { #endif if (UseTLAB) { - filler = allocate_from_gclab(thread, size_with_fwdptr); + copy = allocate_from_gclab(thread, size); } - if (filler == NULL) { - ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size_with_fwdptr); - filler = allocate_memory(req); + if (copy == NULL) { + ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size); + copy = allocate_memory(req); alloc_from_gclab = false; } #ifdef ASSERT } #endif - if (filler == NULL) { - control_thread()->handle_alloc_failure_evac(size_with_fwdptr); + if (copy == NULL) { + control_thread()->handle_alloc_failure_evac(size); _oom_evac_handler.handle_out_of_memory_during_evacuation(); return ShenandoahBarrierSet::resolve_forwarded(p); } - // Copy the object and initialize its forwarding ptr: - HeapWord* copy = filler + ShenandoahBrooksPointer::word_size(); - oop copy_val = oop(copy); - - Copy::aligned_disjoint_words((HeapWord*) p, copy, size_no_fwdptr); - ShenandoahBrooksPointer::initialize(oop(copy)); + // Copy the object: + Copy::aligned_disjoint_words((HeapWord*) p, copy, size); // Try to install the new forwarding pointer. - oop result = ShenandoahBrooksPointer::try_update_forwardee(p, copy_val); - - if (oopDesc::unsafe_equals(result, p)) { + oop copy_val = oop(copy); + oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val); + if (result == copy_val) { // Successfully evacuated. Our copy is now the public one! - evacuated = true; shenandoah_assert_correct(NULL, copy_val); return copy_val; } else { @@ -245,11 +267,11 @@ // have to explicitly overwrite the copy with the filler object. With that overwrite, // we have to keep the fwdptr initialized and pointing to our (stale) copy. if (alloc_from_gclab) { - thread->gclab().rollback(size_with_fwdptr); + thread->gclab().rollback(size); } else { - fill_with_object(copy, size_no_fwdptr); + fill_with_object(copy, size); + shenandoah_assert_correct(NULL, copy_val); } - shenandoah_assert_correct(NULL, copy_val); shenandoah_assert_correct(NULL, result); return result; } @@ -273,13 +295,17 @@ } inline bool ShenandoahHeap::is_idle() const { - return _gc_state.is_unset(MARKING | EVACUATION | UPDATEREFS); + return _gc_state.is_unset(MARKING | EVACUATION | UPDATEREFS | TRAVERSAL); } inline bool ShenandoahHeap::is_concurrent_mark_in_progress() const { return _gc_state.is_set(MARKING); } +inline bool ShenandoahHeap::is_concurrent_traversal_in_progress() const { + return _gc_state.is_set(TRAVERSAL); +} + inline bool ShenandoahHeap::is_evacuation_in_progress() const { return _gc_state.is_set(EVACUATION); } @@ -311,7 +337,7 @@ template inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit) { - assert(ShenandoahBrooksPointer::word_offset() < 0, "skip_delta calculation below assumes the forwarding ptr is before obj"); + assert(! region->is_humongous_continuation(), "no humongous continuation regions here"); ShenandoahMarkingContext* const ctx = complete_marking_context(); assert(ctx->is_complete(), "sanity"); @@ -319,10 +345,9 @@ MarkBitMap* mark_bit_map = ctx->mark_bit_map(); HeapWord* tams = ctx->top_at_mark_start(region); - size_t skip_bitmap_delta = ShenandoahBrooksPointer::word_size() + 1; - size_t skip_objsize_delta = ShenandoahBrooksPointer::word_size() /* + actual obj.size() below */; - HeapWord* start = region->bottom() + ShenandoahBrooksPointer::word_size(); - HeapWord* end = MIN2(tams + ShenandoahBrooksPointer::word_size(), region->end()); + size_t skip_bitmap_delta = 1; + HeapWord* start = region->bottom(); + HeapWord* end = MIN2(tams, region->end()); // Step 1. Scan below the TAMS based on bitmap data. HeapWord* limit_bitmap = MIN2(limit, tams); @@ -352,7 +377,7 @@ do { avail = 0; for (int c = 0; (c < dist) && (cb < limit_bitmap); c++) { - Prefetch::read(cb, ShenandoahBrooksPointer::byte_offset()); + Prefetch::read(cb, oopDesc::mark_offset_in_bytes()); slots[avail++] = cb; cb += skip_bitmap_delta; if (cb < limit_bitmap) { @@ -389,9 +414,9 @@ // Step 2. Accurate size-based traversal, happens past the TAMS. // This restarts the scan at TAMS, which makes sure we traverse all objects, // regardless of what happened at Step 1. - HeapWord* cs = tams + ShenandoahBrooksPointer::word_size(); + HeapWord* cs = tams; while (cs < limit) { - assert (cs > tams, err_msg("only objects past TAMS here: " PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(tams))); + assert (cs >= tams, err_msg("only objects past TAMS here: " PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(tams))); assert (cs < limit, err_msg("only objects below limit here: " PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(limit))); oop obj = oop(cs); int size = obj->size(); @@ -399,7 +424,7 @@ assert(obj->is_oop(), "sanity"); assert(_marking_context->is_marked(obj), "object expected to be marked"); cl->do_object(obj); - cs += size + skip_objsize_delta; + cs += size; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapLock.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapLock.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapLock.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapLock.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP -#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP - -#include "memory/allocation.hpp" -#include "runtime/thread.hpp" - -class ShenandoahHeapLock { -private: - enum LockState { unlocked = 0, locked = 1 }; - - char _pad0[DEFAULT_CACHE_LINE_SIZE]; - volatile int _state; - char _pad1[DEFAULT_CACHE_LINE_SIZE]; - volatile Thread* _owner; - char _pad2[DEFAULT_CACHE_LINE_SIZE]; - -public: - ShenandoahHeapLock() : _state(unlocked), _owner(NULL) {}; - - void lock() { - Thread::SpinAcquire(&_state, "Shenandoah Heap Lock"); -#ifdef ASSERT - assert(_state == locked, "must be locked"); - assert(_owner == NULL, "must not be owned"); - _owner = Thread::current(); -#endif - } - - void unlock() { -#ifdef ASSERT - assert (_owner == Thread::current(), "sanity"); - _owner = NULL; -#endif - Thread::SpinRelease(&_state); - } - -#ifdef ASSERT - void assert_owned_by_current_thread() { - assert(_state == locked, "must be locked"); - assert(_owner == Thread::current(), "must be owned by current thread"); - } - - void assert_not_owned_by_current_thread() { - assert(_owner != Thread::current(), "must be not owned by current thread"); - } - - void assert_owned_by_current_thread_or_safepoint() { - Thread* thr = Thread::current(); - assert((_state == locked && _owner == thr) || - (SafepointSynchronize::is_at_safepoint() && thr->is_VM_thread()), - "must own heap lock or by VM thread at safepoint"); - } -#endif -}; - -class ShenandoahHeapLocker : public StackObj { -private: - ShenandoahHeapLock* _lock; -public: - ShenandoahHeapLocker(ShenandoahHeapLock* lock) { - _lock = lock; - _lock->lock(); - } - - ~ShenandoahHeapLocker() { - _lock->unlock(); - } -}; - -#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -81,10 +81,11 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); jlong status = 0; - if (heap->is_concurrent_mark_in_progress()) status |= 1 << 0; - if (heap->is_evacuation_in_progress()) status |= 1 << 1; - if (heap->is_update_refs_in_progress()) status |= 1 << 2; - _status->set_value(status); + if (heap->is_concurrent_mark_in_progress()) status |= 1 << 0; + if (heap->is_evacuation_in_progress()) status |= 1 << 1; + if (heap->is_update_refs_in_progress()) status |= 1 << 2; + if (heap->is_concurrent_traversal_in_progress()) status |= 1 << 3; + _status->set_value(status); _timestamp->set_value(os::elapsed_counter()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -39,6 +39,7 @@ * - bit 0 set when marking in progress * - bit 1 set when evacuation in progress * - bit 2 set when update refs in progress + * - bit 3 set when traversal in progress * * one variable counter per region, with $max_regions (see above) counters: * - sun.gc.shenandoah.regions.region.$i.data diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "memory/allocation.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" @@ -49,19 +48,25 @@ size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0; size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0; +ShenandoahHeapRegion::PaddedAllocSeqNum ShenandoahHeapRegion::_alloc_seq_num; + ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start, size_t size_words, size_t index, bool committed) : _heap(heap), _reserved(MemRegion(start, size_words)), _region_number(index), _new_top(NULL), - _critical_pins(0), _empty_time(os::elapsedTime()), _state(committed ? _empty_committed : _empty_uncommitted), _tlab_allocs(0), _gclab_allocs(0), _shared_allocs(0), - _live_data(0) { + _seqnum_first_alloc_mutator(0), + _seqnum_first_alloc_gc(0), + _seqnum_last_alloc_mutator(0), + _seqnum_last_alloc_gc(0), + _live_data(0), + _critical_pins(0) { ContiguousSpace::initialize(_reserved, true, committed); } @@ -95,7 +100,8 @@ void ShenandoahHeapRegion::make_regular_bypass() { _heap->assert_heaplock_owned_by_current_thread(); - assert (_heap->is_full_gc_in_progress(), "only for full GC"); + assert (_heap->is_full_gc_in_progress() || _heap->is_degenerated_gc_in_progress(), + "only for full or degen GC"); switch (_state) { case _empty_uncommitted: @@ -177,25 +183,20 @@ void ShenandoahHeapRegion::make_pinned() { _heap->assert_heaplock_owned_by_current_thread(); + assert(pin_count() > 0, err_msg("Should have pins: " SIZE_FORMAT, pin_count())); + switch (_state) { case _regular: - assert (_critical_pins == 0, "sanity"); _state = _pinned; case _pinned_cset: case _pinned: - _critical_pins++; return; case _humongous_start: - assert (_critical_pins == 0, "sanity"); _state = _pinned_humongous_start; case _pinned_humongous_start: - _critical_pins++; return; case _cset: - guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled"); - assert (_critical_pins == 0, "sanity"); _state = _pinned_cset; - _critical_pins++; return; default: report_illegal_transition("pinning"); @@ -204,32 +205,20 @@ void ShenandoahHeapRegion::make_unpinned() { _heap->assert_heaplock_owned_by_current_thread(); + assert(pin_count() == 0, err_msg("Should not have pins: " SIZE_FORMAT, pin_count())); + switch (_state) { case _pinned: - assert (_critical_pins > 0, "sanity"); - _critical_pins--; - if (_critical_pins == 0) { - _state = _regular; - } + _state = _regular; return; case _regular: case _humongous_start: - assert (_critical_pins == 0, "sanity"); return; case _pinned_cset: - guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled"); - assert (_critical_pins > 0, "sanity"); - _critical_pins--; - if (_critical_pins == 0) { - _state = _cset; - } + _state = _cset; return; case _pinned_humongous_start: - assert (_critical_pins > 0, "sanity"); - _critical_pins--; - if (_critical_pins == 0) { - _state = _humongous_start; - } + _state = _humongous_start; return; default: report_illegal_transition("unpinning"); @@ -319,6 +308,10 @@ _tlab_allocs = 0; _gclab_allocs = 0; _shared_allocs = 0; + _seqnum_first_alloc_mutator = 0; + _seqnum_last_alloc_mutator = 0; + _seqnum_first_alloc_gc = 0; + _seqnum_last_alloc_gc = 0; } void ShenandoahHeapRegion::reset_alloc_metadata_to_shared() { @@ -326,6 +319,11 @@ _tlab_allocs = 0; _gclab_allocs = 0; _shared_allocs = used() >> LogHeapWordSize; + uint64_t next = _alloc_seq_num.value++; + _seqnum_first_alloc_mutator = next; + _seqnum_last_alloc_mutator = next; + _seqnum_first_alloc_gc = 0; + _seqnum_last_alloc_gc = 0; } else { reset_alloc_metadata(); } @@ -418,8 +416,10 @@ st->print("|G " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs())); st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs())); st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes())); - st->print("|CP " SIZE_FORMAT_W(3), _critical_pins); - + st->print("|CP " SIZE_FORMAT_W(3), pin_count()); + st->print("|SN " UINT64_FORMAT_X_W(12) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8), + seqnum_first_alloc_mutator(), seqnum_last_alloc_mutator(), + seqnum_first_alloc_gc(), seqnum_last_alloc_gc()); st->cr(); } @@ -457,11 +457,11 @@ if (p >= top()) { return top(); } else { - HeapWord* last = bottom() + ShenandoahBrooksPointer::word_size(); + HeapWord* last = bottom(); HeapWord* cur = last; while (cur <= p) { last = cur; - cur += oop(cur)->size() + ShenandoahBrooksPointer::word_size(); + cur += oop(cur)->size(); } shenandoah_assert_correct(NULL, oop(last)); return last; @@ -475,29 +475,41 @@ size_t region_size; if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) { if (ShenandoahMinRegionSize > max_heap_size / MIN_NUM_REGIONS) { - err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number " - "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "K).", - max_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K); + err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number " + "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size), + MIN_NUM_REGIONS, + byte_size_in_proper_unit(ShenandoahMinRegionSize), + proper_unit_for_byte_size(ShenandoahMinRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMinRegionSize < MIN_REGION_SIZE) { - err_msg message("" SIZE_FORMAT "K should not be lower than minimum region size (" SIZE_FORMAT "K).", - ShenandoahMinRegionSize/K, MIN_REGION_SIZE/K); + err_msg message("" SIZE_FORMAT "%s should not be lower than minimum region size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahMinRegionSize), + proper_unit_for_byte_size(ShenandoahMinRegionSize), + byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMinRegionSize < MinTLABSize) { - err_msg message("" SIZE_FORMAT "K should not be lower than TLAB size size (" SIZE_FORMAT "K).", - ShenandoahMinRegionSize/K, MinTLABSize/K); + err_msg message("" SIZE_FORMAT "%s should not be lower than TLAB size size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahMinRegionSize), + proper_unit_for_byte_size(ShenandoahMinRegionSize), + byte_size_in_proper_unit(MinTLABSize), proper_unit_for_byte_size(MinTLABSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMaxRegionSize < MIN_REGION_SIZE) { - err_msg message("" SIZE_FORMAT "K should not be lower than min region size (" SIZE_FORMAT "K).", - ShenandoahMaxRegionSize/K, MIN_REGION_SIZE/K); + err_msg message("" SIZE_FORMAT "%s should not be lower than min region size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahMaxRegionSize), + proper_unit_for_byte_size(ShenandoahMaxRegionSize), + byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE)); vm_exit_during_initialization("Invalid -XX:ShenandoahMaxRegionSize option", message); } if (ShenandoahMinRegionSize > ShenandoahMaxRegionSize) { - err_msg message("Minimum (" SIZE_FORMAT "K) should be larger than maximum (" SIZE_FORMAT "K).", - ShenandoahMinRegionSize/K, ShenandoahMaxRegionSize/K); + err_msg message("Minimum (" SIZE_FORMAT "%s) should be larger than maximum (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahMinRegionSize), + proper_unit_for_byte_size(ShenandoahMinRegionSize), + byte_size_in_proper_unit(ShenandoahMaxRegionSize), + proper_unit_for_byte_size(ShenandoahMaxRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize or -XX:ShenandoahMaxRegionSize", message); } @@ -511,19 +523,28 @@ } else { if (ShenandoahHeapRegionSize > max_heap_size / MIN_NUM_REGIONS) { - err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number " - "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "K).", - max_heap_size/K, MIN_NUM_REGIONS, ShenandoahHeapRegionSize/K); + err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number " + "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size), + MIN_NUM_REGIONS, + byte_size_in_proper_unit(ShenandoahHeapRegionSize), + proper_unit_for_byte_size(ShenandoahHeapRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message); } if (ShenandoahHeapRegionSize < ShenandoahMinRegionSize) { - err_msg message("Heap region size (" SIZE_FORMAT "K) should be larger than min region size (" SIZE_FORMAT "K).", - ShenandoahHeapRegionSize/K, ShenandoahMinRegionSize/K); + err_msg message("Heap region size (" SIZE_FORMAT "%s) should be larger than min region size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahHeapRegionSize), + proper_unit_for_byte_size(ShenandoahHeapRegionSize), + byte_size_in_proper_unit(ShenandoahMinRegionSize), + proper_unit_for_byte_size(ShenandoahMinRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message); } if (ShenandoahHeapRegionSize > ShenandoahMaxRegionSize) { - err_msg message("Heap region size (" SIZE_FORMAT "K) should be lower than max region size (" SIZE_FORMAT "K).", - ShenandoahHeapRegionSize/K, ShenandoahMaxRegionSize/K); + err_msg message("Heap region size (" SIZE_FORMAT "%s) should be lower than max region size (" SIZE_FORMAT "%s).", + byte_size_in_proper_unit(ShenandoahHeapRegionSize), + proper_unit_for_byte_size(ShenandoahHeapRegionSize), + byte_size_in_proper_unit(ShenandoahMaxRegionSize), + proper_unit_for_byte_size(ShenandoahMaxRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message); } region_size = ShenandoahHeapRegionSize; @@ -631,3 +652,18 @@ } _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes()); } + +void ShenandoahHeapRegion::record_pin() { + Atomic::add(1, &_critical_pins); +} + +void ShenandoahHeapRegion::record_unpin() { + assert(pin_count() > 0, err_msg("Region " SIZE_FORMAT " should have non-zero pins", region_number())); + Atomic::add(-1, &_critical_pins); +} + +size_t ShenandoahHeapRegion::pin_count() const { + jint v = OrderAccess::load_acquire((volatile jint*)&_critical_pins); + assert(v >= 0, "sanity"); + return (size_t)v; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -190,11 +190,15 @@ // Macro-properties: bool is_alloc_allowed() const { return is_empty() || is_regular() || _state == _pinned; } - bool is_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); } + bool is_stw_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); } RegionState state() const { return _state; } int state_ordinal() const { return region_state_to_ordinal(_state); } + void record_pin(); + void record_unpin(); + size_t pin_count() const; + private: static size_t RegionCount; static size_t RegionSizeBytes; @@ -208,6 +212,21 @@ static size_t MaxTLABSizeBytes; static size_t MaxTLABSizeWords; + // Global allocation counter, increased for each allocation under Shenandoah heap lock. + // Padded to avoid false sharing with the read-only fields above. + struct PaddedAllocSeqNum { + char _pad0[DEFAULT_CACHE_LINE_SIZE]; + uint64_t value; + char _pad1[DEFAULT_CACHE_LINE_SIZE]; + + PaddedAllocSeqNum() { + // start with 1, reserve 0 for uninitialized value + value = 1; + } + }; + + static PaddedAllocSeqNum _alloc_seq_num; + // Never updated fields ShenandoahHeap* _heap; MemRegion _reserved; @@ -215,7 +234,6 @@ // Rarely updated fields HeapWord* _new_top; - size_t _critical_pins; double _empty_time; // Seldom updated fields @@ -226,7 +244,13 @@ size_t _gclab_allocs; size_t _shared_allocs; + uint64_t _seqnum_first_alloc_mutator; + uint64_t _seqnum_first_alloc_gc; + uint64_t _seqnum_last_alloc_mutator; + uint64_t _seqnum_last_alloc_gc; + volatile jint _live_data; + volatile jint _critical_pins; // Claim some space at the end to protect next region char _pad0[DEFAULT_CACHE_LINE_SIZE]; @@ -314,6 +338,11 @@ return ShenandoahHeapRegion::MaxTLABSizeWords; } + static uint64_t seqnum_current_alloc() { + // Last used seq number + return _alloc_seq_num.value - 1; + } + size_t region_number() const; // Allocation (return NULL if full) @@ -360,6 +389,32 @@ size_t get_tlab_allocs() const; size_t get_gclab_allocs() const; + uint64_t seqnum_first_alloc() const { + if (_seqnum_first_alloc_mutator == 0) return _seqnum_first_alloc_gc; + if (_seqnum_first_alloc_gc == 0) return _seqnum_first_alloc_mutator; + return MIN2(_seqnum_first_alloc_mutator, _seqnum_first_alloc_gc); + } + + uint64_t seqnum_last_alloc() const { + return MAX2(_seqnum_last_alloc_mutator, _seqnum_last_alloc_gc); + } + + uint64_t seqnum_first_alloc_mutator() const { + return _seqnum_first_alloc_mutator; + } + + uint64_t seqnum_last_alloc_mutator() const { + return _seqnum_last_alloc_mutator; + } + + uint64_t seqnum_first_alloc_gc() const { + return _seqnum_first_alloc_gc; + } + + uint64_t seqnum_last_alloc_gc() const { + return _seqnum_last_alloc_gc; + } + private: void do_commit(); void do_uncommit(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -52,6 +52,29 @@ } inline void ShenandoahHeapRegion::adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t size) { + bool is_first_alloc = (top() == bottom()); + + switch (type) { + case ShenandoahAllocRequest::_alloc_shared: + case ShenandoahAllocRequest::_alloc_tlab: + _seqnum_last_alloc_mutator = _alloc_seq_num.value++; + if (is_first_alloc) { + assert (_seqnum_first_alloc_mutator == 0, err_msg("Region " SIZE_FORMAT " metadata is correct", _region_number)); + _seqnum_first_alloc_mutator = _seqnum_last_alloc_mutator; + } + break; + case ShenandoahAllocRequest::_alloc_shared_gc: + case ShenandoahAllocRequest::_alloc_gclab: + _seqnum_last_alloc_gc = _alloc_seq_num.value++; + if (is_first_alloc) { + assert (_seqnum_first_alloc_gc == 0, err_msg("Region " SIZE_FORMAT " metadata is correct", _region_number)); + _seqnum_first_alloc_gc = _seqnum_last_alloc_gc; + } + break; + default: + ShouldNotReachHere(); + } + switch (type) { case ShenandoahAllocRequest::_alloc_shared: case ShenandoahAllocRequest::_alloc_shared_gc: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "gc_interface/gcCause.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" @@ -40,6 +39,14 @@ else return 0; } +int ShenandoahHeuristics::compare_by_garbage_then_alloc_seq_ascending(RegionData a, RegionData b) { + int r = compare_by_garbage(a, b); + if (r != 0) { + return r; + } + return compare_by_alloc_seq_ascending(a, b); +} + int ShenandoahHeuristics::compare_by_alloc_seq_ascending(RegionData a, RegionData b) { if (a._seqnum_last_alloc == b._seqnum_last_alloc) return 0; @@ -112,6 +119,9 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); + // Check all pinned regions have updated status before choosing the collection set. + heap->assert_pinned_region_status(); + // Step 1. Build up the region candidates we care about, rejecting losers and accepting winners right away. size_t num_regions = heap->num_regions(); @@ -155,7 +165,7 @@ // Reclaim humongous regions here, and count them as the immediate garbage #ifdef ASSERT bool reg_live = region->has_live(); - bool bm_live = ctx->is_marked(oop(region->bottom() + ShenandoahBrooksPointer::word_size())); + bool bm_live = ctx->is_marked(oop(region->bottom())); assert(reg_live == bm_live, err_msg("Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words())); @@ -178,8 +188,9 @@ // given the amount of immediately reclaimable garbage. If we do, figure out the collection set. assert (immediate_garbage <= total_garbage, - err_msg("Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "M vs " SIZE_FORMAT "M", - immediate_garbage / M, total_garbage / M)); + err_msg("Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "%s vs " SIZE_FORMAT "%s", + byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage), + byte_size_in_proper_unit(total_garbage), proper_unit_for_byte_size(total_garbage))); size_t immediate_percent = total_garbage == 0 ? 0 : (immediate_garbage * 100 / total_garbage); @@ -188,13 +199,17 @@ collection_set->update_region_status(); size_t cset_percent = total_garbage == 0 ? 0 : (collection_set->garbage() * 100 / total_garbage); - log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "M (" SIZE_FORMAT "%% of total), " SIZE_FORMAT "M CSet, " SIZE_FORMAT " CSet regions", - collection_set->garbage() / M, cset_percent, collection_set->live_data() / M, collection_set->count()); + log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%% of total), " SIZE_FORMAT "%s CSet, " SIZE_FORMAT " CSet regions", + byte_size_in_proper_unit(collection_set->garbage()), proper_unit_for_byte_size(collection_set->garbage()), + cset_percent, + byte_size_in_proper_unit(collection_set->live_data()), proper_unit_for_byte_size(collection_set->live_data()), + collection_set->count()); } end_choose_collection_set(); - log_info(gc, ergo)("Immediate Garbage: " SIZE_FORMAT "M (" SIZE_FORMAT "%% of total), " SIZE_FORMAT " regions", - immediate_garbage / M, immediate_percent, immediate_regions); + log_info(gc, ergo)("Immediate Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%% of total), " SIZE_FORMAT " regions", + byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage), + immediate_percent, immediate_regions); } void ShenandoahHeuristics::record_gc_start() { @@ -302,7 +317,7 @@ return os::elapsedTime() - _cycle_start; } -bool ShenandoahHeuristics::should_start_normal_gc() const { +bool ShenandoahHeuristics::should_start_gc() const { // Perform GC to cleanup metaspace if (has_metaspace_oom()) { // Some of vmTestbase/metaspace tests depend on following line to count GC cycles diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -100,6 +100,7 @@ ShenandoahSharedFlag _metaspace_oom; static int compare_by_garbage(RegionData a, RegionData b); + static int compare_by_garbage_then_alloc_seq_ascending(RegionData a, RegionData b); static int compare_by_alloc_seq_ascending(RegionData a, RegionData b); static int compare_by_alloc_seq_descending(RegionData a, RegionData b); @@ -127,7 +128,7 @@ virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs); - virtual bool should_start_normal_gc() const; + virtual bool should_start_gc() const; virtual bool should_start_update_refs(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahLock.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahLock.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahLock.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahLock.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP + +#include "memory/allocation.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/thread.hpp" + +class ShenandoahLock { +private: + enum LockState { unlocked = 0, locked = 1 }; + + char _pad0[DEFAULT_CACHE_LINE_SIZE]; + volatile int _state; + char _pad1[DEFAULT_CACHE_LINE_SIZE]; + volatile Thread* _owner; + char _pad2[DEFAULT_CACHE_LINE_SIZE]; + +public: + ShenandoahLock() : _state(unlocked), _owner(NULL) {}; + + void lock() { +#ifdef ASSERT + assert(_owner != Thread::current(), "reentrant locking attempt, would deadlock"); +#endif + Thread::SpinAcquire(&_state, "Shenandoah Heap Lock"); +#ifdef ASSERT + assert(_state == locked, "must be locked"); + assert(_owner == NULL, "must not be owned"); + _owner = Thread::current(); +#endif + } + + void unlock() { +#ifdef ASSERT + assert (_owner == Thread::current(), "sanity"); + _owner = NULL; +#endif + Thread::SpinRelease(&_state); + } + +#ifdef ASSERT + void assert_owned_by_current_thread() { + assert(_state == locked, "must be locked"); + assert(_owner == Thread::current(), "must be owned by current thread"); + } + + void assert_not_owned_by_current_thread() { + assert(_owner != Thread::current(), "must be not owned by current thread"); + } + + void assert_owned_by_current_thread_or_safepoint() { + Thread* thr = Thread::current(); + assert((_state == locked && _owner == thr) || + (SafepointSynchronize::is_at_safepoint() && thr->is_VM_thread()), + "must own heap lock or by VM thread at safepoint"); + } +#endif +}; + +class ShenandoahLocker : public StackObj { +private: + ShenandoahLock* _lock; +public: + ShenandoahLocker(ShenandoahLock* lock) { + _lock = lock; + _lock->lock(); + } + + ~ShenandoahLocker() { + _lock->unlock(); + } +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,7 +26,8 @@ #include "code/codeCache.hpp" #include "gc_implementation/shenandoah/shenandoahGCTraceTime.hpp" #include "gc_implementation/shared/gcTimer.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc_implementation/shenandoah/preservedMarks.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" @@ -38,6 +39,7 @@ #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc_implementation/shenandoah/shenandoahRootProcessor.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" #include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp" #include "gc_implementation/shenandoah/shenandoahUtils.hpp" #include "gc_implementation/shenandoah/shenandoahVerifier.hpp" @@ -46,11 +48,16 @@ #include "gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp" #include "memory/metaspace.hpp" #include "oops/oop.inline.hpp" +#include "runtime/biasedLocking.hpp" #include "runtime/thread.hpp" #include "utilities/copy.hpp" #include "utilities/growableArray.hpp" #include "utilities/workgroup.hpp" +ShenandoahMarkCompact::ShenandoahMarkCompact() : + _gc_timer(NULL), + _preserved_marks(new PreservedMarksSet(true)) {} + void ShenandoahMarkCompact::initialize(GCTimer* gc_timer) { _gc_timer = gc_timer; } @@ -80,28 +87,34 @@ ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_prepare); // Full GC is supposed to recover from any GC state: - // 0. Remember if we have forwarded objects + // a0. Remember if we have forwarded objects bool has_forwarded_objects = heap->has_forwarded_objects(); - // a. Cancel concurrent mark, if in progress - if (heap->is_concurrent_mark_in_progress()) { - heap->concurrent_mark()->cancel(); - heap->stop_concurrent_marking(); - } - assert(!heap->is_concurrent_mark_in_progress(), "sanity"); - - // b1. Cancel evacuation, if in progress + // a1. Cancel evacuation, if in progress if (heap->is_evacuation_in_progress()) { heap->set_evacuation_in_progress(false); } assert(!heap->is_evacuation_in_progress(), "sanity"); - // b2. Cancel update-refs, if in progress + // a2. Cancel update-refs, if in progress if (heap->is_update_refs_in_progress()) { heap->set_update_refs_in_progress(false); } assert(!heap->is_update_refs_in_progress(), "sanity"); + // a3. Cancel concurrent traversal GC, if in progress + if (heap->is_concurrent_traversal_in_progress()) { + heap->traversal_gc()->reset(); + heap->set_concurrent_traversal_in_progress(false); + } + + // b. Cancel concurrent mark, if in progress + if (heap->is_concurrent_mark_in_progress()) { + heap->concurrent_mark()->cancel(); + heap->stop_concurrent_marking(); + } + assert(!heap->is_concurrent_mark_in_progress(), "sanity"); + // c. Reset the bitmaps for new marking heap->reset_mark_bitmap(); assert(heap->marking_context()->is_bitmap_clear(), "sanity"); @@ -115,6 +128,13 @@ // e. Set back forwarded objects bit back, in case some steps above dropped it. heap->set_has_forwarded_objects(has_forwarded_objects); + + // f. Sync pinned region status from the CP marks + heap->sync_pinned_region_status(); + + // The rest of prologue: + BiasedLocking::preserve_marks(); + _preserved_marks->init(heap->workers()->active_workers()); } heap->make_parsable(true); @@ -155,6 +175,16 @@ phase4_compact_objects(worker_slices); } + { + // Epilogue + SharedRestorePreservedMarksTaskExecutor exec(heap->workers()); + _preserved_marks->restore(&exec); + BiasedLocking::restore_marks(); + _preserved_marks->reclaim(); + + JvmtiExport::gc_epilogue(); + } + // Resize metaspace MetaspaceGC::compute_new_size(); @@ -231,6 +261,7 @@ class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure { private: + PreservedMarks* const _preserved_marks; ShenandoahHeap* const _heap; GrowableArray& _empty_regions; int _empty_regions_pos; @@ -239,7 +270,10 @@ HeapWord* _compact_point; public: - ShenandoahPrepareForCompactionObjectClosure(GrowableArray& empty_regions, ShenandoahHeapRegion* to_region) : + ShenandoahPrepareForCompactionObjectClosure(PreservedMarks* preserved_marks, + GrowableArray& empty_regions, + ShenandoahHeapRegion* to_region) : + _preserved_marks(preserved_marks), _heap(ShenandoahHeap::heap()), _empty_regions(empty_regions), _empty_regions_pos(0), @@ -269,7 +303,7 @@ assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); assert(!_heap->complete_marking_context()->allocated_after_mark_start((HeapWord*) p), "must be truly marked"); - size_t obj_size = p->size() + ShenandoahBrooksPointer::word_size(); + size_t obj_size = p->size(); if (_compact_point + obj_size > _to_region->end()) { finish_region(); @@ -292,13 +326,15 @@ // Object fits into current region, record new location: assert(_compact_point + obj_size <= _to_region->end(), "must fit"); shenandoah_assert_not_forwarded(NULL, p); - ShenandoahBrooksPointer::set_raw(p, _compact_point + ShenandoahBrooksPointer::word_size()); + _preserved_marks->push_if_necessary(p, p->mark()); + p->forward_to(oop(_compact_point)); _compact_point += obj_size; } }; class ShenandoahPrepareForCompactionTask : public AbstractGangTask { private: + PreservedMarksSet* const _preserved_marks; ShenandoahHeap* const _heap; ShenandoahHeapRegionSet** const _worker_slices; ShenandoahRegionIterator _heap_regions; @@ -306,14 +342,25 @@ ShenandoahHeapRegion* next_from_region(ShenandoahHeapRegionSet* slice) { ShenandoahHeapRegion* from_region = _heap_regions.next(); - while (from_region != NULL && (!from_region->is_move_allowed() || from_region->is_humongous())) { + // Look for next candidate for this slice: + while (from_region != NULL) { + // Empty region: get it into the slice to defragment the slice itself. + // We could have skipped this without violating correctness, but we really + // want to compact all live regions to the start of the heap, which sometimes + // means moving them into the fully empty regions. + if (from_region->is_empty()) break; + + // Can move the region, and this is not the humongous region. Humongous + // moves are special cased here, because their moves are handled separately. + if (from_region->is_stw_move_allowed() && !from_region->is_humongous()) break; + from_region = _heap_regions.next(); } if (from_region != NULL) { assert(slice != NULL, "sanity"); assert(!from_region->is_humongous(), "this path cannot handle humongous regions"); - assert(from_region->is_move_allowed(), "only regions that can be moved in mark-compact"); + assert(from_region->is_empty() || from_region->is_stw_move_allowed(), "only regions that can be moved in mark-compact"); slice->add_region(from_region); } @@ -321,9 +368,10 @@ } public: - ShenandoahPrepareForCompactionTask(ShenandoahHeapRegionSet** worker_slices) : - AbstractGangTask("Shenandoah Prepare For Compaction Task"), - _heap(ShenandoahHeap::heap()), _worker_slices(worker_slices) { + ShenandoahPrepareForCompactionTask(PreservedMarksSet* preserved_marks, ShenandoahHeapRegionSet** worker_slices) : + AbstractGangTask("Shenandoah Prepare For Compaction Task"), + _preserved_marks(preserved_marks), + _heap(ShenandoahHeap::heap()), _worker_slices(worker_slices) { } void work(uint worker_id) { @@ -339,7 +387,7 @@ // Remember empty regions and reuse them as needed. ResourceMark rm; GrowableArray empty_regions((int)_heap->num_regions()); - ShenandoahPrepareForCompactionObjectClosure cl(empty_regions, from_region); + ShenandoahPrepareForCompactionObjectClosure cl(_preserved_marks->get(worker_id), empty_regions, from_region); while (from_region != NULL) { cl.set_from_region(from_region); if (from_region->has_live()) { @@ -379,25 +427,26 @@ size_t to_begin = heap->num_regions(); size_t to_end = heap->num_regions(); - for (size_t c = heap->num_regions() - 1; c > 0; c--) { - ShenandoahHeapRegion *r = heap->get_region(c); + for (size_t c = heap->num_regions(); c > 0; c--) { + ShenandoahHeapRegion *r = heap->get_region(c - 1); if (r->is_humongous_continuation() || (r->new_top() == r->bottom())) { // To-region candidate: record this, and continue scan to_begin = r->region_number(); continue; } - if (r->is_humongous_start() && r->is_move_allowed()) { + if (r->is_humongous_start() && r->is_stw_move_allowed()) { // From-region candidate: movable humongous region - oop old_obj = oop(r->bottom() + ShenandoahBrooksPointer::word_size()); - size_t words_size = old_obj->size() + ShenandoahBrooksPointer::word_size(); + oop old_obj = oop(r->bottom()); + size_t words_size = old_obj->size(); size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); size_t start = to_end - num_regions; if (start >= to_begin && start != r->region_number()) { // Fits into current window, and the move is non-trivial. Record the move then, and continue scan. - ShenandoahBrooksPointer::set_raw(old_obj, heap->get_region(start)->bottom() + ShenandoahBrooksPointer::word_size()); + _preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark()); + old_obj->forward_to(oop(heap->get_region(start)->bottom())); to_end = start; continue; } @@ -445,7 +494,7 @@ void heap_region_do(ShenandoahHeapRegion* r) { if (r->is_humongous_start()) { - oop humongous_obj = oop(r->bottom() + ShenandoahBrooksPointer::word_size()); + oop humongous_obj = oop(r->bottom()); if (!_ctx->is_marked(humongous_obj)) { assert(!r->has_live(), err_msg("Region " SIZE_FORMAT " is not marked, should not have live", r->region_number())); @@ -471,6 +520,10 @@ GCTraceTime time("Phase 2: Compute new object addresses", ShenandoahLogDebug, _gc_timer, heap->tracer()->gc_id()); ShenandoahGCPhase calculate_address_phase(ShenandoahPhaseTimings::full_gc_calculate_addresses); + // About to figure out which regions can be compacted, make sure pinning status + // had been updated in GC prologue. + heap->assert_pinned_region_status(); + { // Trash the immediately collectible regions before computing addresses ShenandoahTrashImmediateGarbageClosure tigcl; @@ -485,7 +538,7 @@ // Compute the new addresses for regular objects { ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_calculate_addresses_regular); - ShenandoahPrepareForCompactionTask prepare_task(worker_slices); + ShenandoahPrepareForCompactionTask prepare_task(_preserved_marks, worker_slices); heap->workers()->run_task(&prepare_task); } @@ -507,9 +560,11 @@ if (! oopDesc::is_null(o)) { oop obj = oopDesc::decode_heap_oop_not_null(o); assert(_ctx->is_marked(obj), "must be marked"); - oop forw = oop(ShenandoahBrooksPointer::get_raw(obj)); - oopDesc::encode_store_heap_oop(p, forw); - } + if (obj->is_forwarded()) { + oop forw = obj->forwardee(); + oopDesc::encode_store_heap_oop(p, forw); + } + } } public: @@ -562,11 +617,12 @@ class ShenandoahAdjustRootPointersTask : public AbstractGangTask { private: ShenandoahRootProcessor* _rp; - + PreservedMarksSet* _preserved_marks; public: - ShenandoahAdjustRootPointersTask(ShenandoahRootProcessor* rp) : + ShenandoahAdjustRootPointersTask(ShenandoahRootProcessor* rp, PreservedMarksSet* preserved_marks) : AbstractGangTask("Shenandoah Adjust Root Pointers Task"), - _rp(rp) {} + _rp(rp), + _preserved_marks(preserved_marks) {} void work(uint worker_id) { ShenandoahAdjustPointersClosure cl; @@ -574,9 +630,10 @@ MarkingCodeBlobClosure adjust_code_closure(&cl, CodeBlobToOopClosure::FixRelocations); - _rp->process_all_roots(&cl, &cl, + _rp->process_all_roots(&cl, &adjust_cld_closure, &adjust_code_closure, NULL, worker_id); + _preserved_marks->get(worker_id)->adjust_during_full_gc(); } }; @@ -590,7 +647,7 @@ { COMPILER2_PRESENT(DerivedPointerTable::clear()); ShenandoahRootProcessor rp(heap, nworkers, ShenandoahPhaseTimings::full_gc_roots); - ShenandoahAdjustRootPointersTask task(&rp); + ShenandoahAdjustRootPointersTask task(&rp, _preserved_marks); workers->run_task(&task); COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); } @@ -609,13 +666,13 @@ void do_object(oop p) { assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); size_t size = (size_t)p->size(); - HeapWord* compact_to = ShenandoahBrooksPointer::get_raw(p); - HeapWord* compact_from = (HeapWord*) p; - if (compact_from != compact_to) { + if (p->is_forwarded()) { + HeapWord* compact_from = (HeapWord*) p; + HeapWord* compact_to = (HeapWord*) p->forwardee(); Copy::aligned_conjoint_words(compact_from, compact_to, size); + oop new_obj = oop(compact_to); + new_obj->init_mark(); } - oop new_obj = oop(compact_to); - ShenandoahBrooksPointer::initialize(new_obj); } }; @@ -706,31 +763,30 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); - for (size_t c = heap->num_regions() - 1; c > 0; c--) { - ShenandoahHeapRegion* r = heap->get_region(c); + for (size_t c = heap->num_regions(); c > 0; c--) { + ShenandoahHeapRegion* r = heap->get_region(c - 1); if (r->is_humongous_start()) { - oop old_obj = oop(r->bottom() + ShenandoahBrooksPointer::word_size()); - size_t words_size = old_obj->size() + ShenandoahBrooksPointer::word_size(); + oop old_obj = oop(r->bottom()); + if (!old_obj->is_forwarded()) { + // No need to move the object, it stays at the same slot + continue; + } + size_t words_size = old_obj->size(); size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); size_t old_start = r->region_number(); size_t old_end = old_start + num_regions - 1; - size_t new_start = heap->heap_region_index_containing(ShenandoahBrooksPointer::get_raw(old_obj)); + size_t new_start = heap->heap_region_index_containing(old_obj->forwardee()); size_t new_end = new_start + num_regions - 1; - - if (old_start == new_start) { - // No need to move the object, it stays at the same slot - continue; - } - - assert (r->is_move_allowed(), "should be movable"); + assert(old_start != new_start, "must be real move"); + assert(r->is_stw_move_allowed(), err_msg("Region " SIZE_FORMAT " should be movable", r->region_number())); Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(), heap->get_region(new_start)->bottom(), ShenandoahHeapRegion::region_size_words()*num_regions); - oop new_obj = oop(heap->get_region(new_start)->bottom() + ShenandoahBrooksPointer::word_size()); - ShenandoahBrooksPointer::initialize(new_obj); + oop new_obj = oop(heap->get_region(new_start)->bottom()); + new_obj->init_mark(); { for (size_t c = old_start; c <= old_end; c++) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -49,12 +49,19 @@ * where it does sliding compaction, without interfering with other threads. */ +class PreservedMarksSet; + class ShenandoahMarkCompact : public CHeapObj { + friend class ShenandoahPrepareForCompactionObjectClosure; private: GCTimer* _gc_timer; + PreservedMarksSet* _preserved_marks; + public: + ShenandoahMarkCompact(); void initialize(GCTimer* gc_timer); + void do_it(GCCause::Cause gc_cause); private: @@ -65,7 +72,6 @@ void calculate_target_humongous_objects(); void compact_humongous_objects(); - }; #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKCOMPACT_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -127,48 +127,52 @@ _ef_after = ShenandoahMetrics::external_fragmentation(); } -void ShenandoahMetricsSnapshot::print() { - log_info(gc, ergo)("Used: before: " SIZE_FORMAT "M, after: " SIZE_FORMAT "M", _used_before/M, _used_after/M); - log_info(gc, ergo)("Internal frag: before: %.1f%%, after: %.1f%%", _if_before * 100, _if_after * 100); - log_info(gc, ergo)("External frag: before: %.1f%%, after: %.1f%%", _ef_before * 100, _ef_after * 100); -} - -bool ShenandoahMetricsSnapshot::is_good_progress(const char *label) { - // Under the critical threshold? Declare failure. +bool ShenandoahMetricsSnapshot::is_good_progress() { + // Under the critical threshold? size_t free_actual = _heap->free_set()->available(); size_t free_expected = _heap->max_capacity() / 100 * ShenandoahCriticalFreeThreshold; - if (free_actual < free_expected) { - log_info(gc, ergo)("Not enough free space (" SIZE_FORMAT "M, need " SIZE_FORMAT "M) after %s", - free_actual / M, free_expected / M, label); + bool prog_free = free_actual >= free_expected; + log_info(gc, ergo)("%s progress for free space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", + prog_free ? "Good" : "Bad", + byte_size_in_proper_unit(free_actual), proper_unit_for_byte_size(free_actual), + byte_size_in_proper_unit(free_expected), proper_unit_for_byte_size(free_expected)); + if (!prog_free) { return false; } - // Freed up enough? Good! Declare victory. + // Freed up enough? size_t progress_actual = (_used_before > _used_after) ? _used_before - _used_after : 0; size_t progress_expected = ShenandoahHeapRegion::region_size_bytes(); - if (progress_actual >= progress_expected) { + bool prog_used = progress_actual >= progress_expected; + log_info(gc, ergo)("%s progress for used space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", + prog_used ? "Good" : "Bad", + byte_size_in_proper_unit(progress_actual), proper_unit_for_byte_size(progress_actual), + byte_size_in_proper_unit(progress_expected), proper_unit_for_byte_size(progress_expected)); + if (prog_used) { return true; } - log_info(gc,ergo)("Not enough progress (" SIZE_FORMAT "M, need " SIZE_FORMAT "M) after %s", - progress_actual / M, progress_expected / M, label); - // Internal fragmentation is down? Good! Declare victory. + // Internal fragmentation is down? double if_actual = _if_before - _if_after; double if_expected = 0.01; // 1% should be enough - if (if_actual > if_expected) { + bool prog_if = if_actual >= if_expected; + log_info(gc, ergo)("%s progress for internal fragmentation: %.1f%%, need %.1f%%", + prog_if ? "Good" : "Bad", + if_actual * 100, if_expected * 100); + if (prog_if) { return true; } - log_info(gc,ergo)("Not enough internal fragmentation improvement (%.1f%%, need %.1f%%) after %s", - if_actual * 100, if_expected * 100, label); - // External fragmentation is down? Good! Declare victory. + // External fragmentation is down? double ef_actual = _ef_before - _ef_after; double ef_expected = 0.01; // 1% should be enough - if (ef_actual > ef_expected) { + bool prog_ef = ef_actual >= ef_expected; + log_info(gc, ergo)("%s progress for external fragmentation: %.1f%%, need %.1f%%", + prog_ef ? "Good" : "Bad", + ef_actual * 100, ef_expected * 100); + if (prog_ef) { return true; } - log_info(gc,ergo)("Not enough external fragmentation improvement (%.1f%%, need %.1f%%) after %s", - if_actual * 100, if_expected * 100, label); // Nothing good had happened. return false; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMetrics.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -47,9 +47,8 @@ void snap_before(); void snap_after(); - void print(); - bool is_good_progress(const char *label); + bool is_good_progress(); }; #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHMETRICS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP + +#include "memory/allocation.hpp" + +class ShenandoahHeuristics; + +class ShenandoahMode : public CHeapObj { +public: + virtual void initialize_flags() const = 0; + virtual ShenandoahHeuristics* initialize_heuristics() const = 0; +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahNormalMode.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" + +void ShenandoahNormalMode::initialize_flags() const { + SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); + SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); + + // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); +} + +ShenandoahHeuristics* ShenandoahNormalMode::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"); + } + } + ShouldNotReachHere(); + return NULL; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP + +#include "gc_implementation/shenandoah/shenandoahMode.hpp" + +class ShenandoahHeuristics; + +class ShenandoahNormalMode : public ShenandoahMode { +public: + virtual void initialize_flags() const; + virtual ShenandoahHeuristics* initialize_heuristics() const; +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahOopClosures.hpp" +#include "runtime/thread.hpp" + +ShenandoahTraversalSuperClosure::ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) : + MetadataAwareOopClosure(rp), + _traversal_gc(ShenandoahHeap::heap()->traversal_gc()), + _dedup_queue(dq), + _thread(Thread::current()), + _queue(q), + _mark_context(ShenandoahHeap::heap()->marking_context()) { +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,11 +24,14 @@ #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP +#include "memory/iterator.hpp" #include "gc_implementation/shenandoah/shenandoahTaskqueue.hpp" class ShenandoahHeap; class ShenandoahStrDedupQueue; class ShenandoahMarkingContext; +class ShenandoahTraversalGC; +class OopClosure; enum UpdateRefsMode { NONE, // No reference updating @@ -200,4 +203,154 @@ virtual void do_oop(oop* p) { do_oop_nv(p); } }; +class ShenandoahTraversalSuperClosure : public MetadataAwareOopClosure { +private: + ShenandoahTraversalGC* const _traversal_gc; + ShenandoahStrDedupQueue* const _dedup_queue; + Thread* const _thread; + ShenandoahObjToScanQueue* const _queue; + ShenandoahMarkingContext* const _mark_context; +protected: + ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq = NULL); + + template + void work(T* p); + +}; + +class ShenandoahTraversalRootsClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalRootsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahTraversalSuperClosure(q, rp) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return false; } +}; + +class ShenandoahTraversalClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahTraversalSuperClosure(q, rp) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return false; } +}; + +class ShenandoahTraversalMetadataClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahTraversalSuperClosure(q, rp) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return true; } +}; + +class ShenandoahTraversalDedupClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) : + ShenandoahTraversalSuperClosure(q, rp, dq) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return false; } +}; + +class ShenandoahTraversalMetadataDedupClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) : + ShenandoahTraversalSuperClosure(q, rp, dq) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return true; } +}; + +class ShenandoahTraversalDegenClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahTraversalSuperClosure(q, rp) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return false; } +}; + +class ShenandoahTraversalMetadataDegenClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalMetadataDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahTraversalSuperClosure(q, rp) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return true; } +}; + +class ShenandoahTraversalDedupDegenClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) : + ShenandoahTraversalSuperClosure(q, rp, dq) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return false; } +}; + +class ShenandoahTraversalMetadataDedupDegenClosure : public ShenandoahTraversalSuperClosure { +private: + template + inline void do_oop_work(T* p) { work(p); } + +public: + ShenandoahTraversalMetadataDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) : + ShenandoahTraversalSuperClosure(q, rp, dq) {} + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + virtual bool do_metadata() { return true; } +}; + #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,6 +26,7 @@ #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.inline.hpp" template inline void ShenandoahMarkRefsSuperClosure::work(T *p) { @@ -37,4 +38,9 @@ _heap->maybe_update_with_forwarded(p); } +template +inline void ShenandoahTraversalSuperClosure::work(T* p) { + _traversal_gc->process_oop(p, _thread, _queue, _mark_context, _dedup_queue); +} + #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_INLINE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -70,9 +70,12 @@ restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Mark. Expected Live: " SIZE_FORMAT "M, Free: " SIZE_FORMAT - "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx", - live / M, free / M, non_taxable / M, tax); + log_info(gc, ergo)("Pacer for Mark. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " + "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + byte_size_in_proper_unit(live), proper_unit_for_byte_size(live), + byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), + byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), + tax); } void ShenandoahPacer::setup_for_evac() { @@ -91,9 +94,12 @@ restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Evacuation. Used CSet: " SIZE_FORMAT "M, Free: " SIZE_FORMAT - "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx", - used / M, free / M, non_taxable / M, tax); + log_info(gc, ergo)("Pacer for Evacuation. Used CSet: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " + "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + byte_size_in_proper_unit(used), proper_unit_for_byte_size(used), + byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), + byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), + tax); } void ShenandoahPacer::setup_for_updaterefs() { @@ -112,9 +118,39 @@ restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "M, Free: " SIZE_FORMAT - "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx", - used / M, free / M, non_taxable / M, tax); + log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " + "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + byte_size_in_proper_unit(used), proper_unit_for_byte_size(used), + byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), + byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), + tax); +} + +/* + * Traversal walks the entire heap once, and therefore we have to make assumptions about its + * liveness, like concurrent mark does. + */ + +void ShenandoahPacer::setup_for_traversal() { + assert(ShenandoahPacing, "Only be here when pacing is enabled"); + + size_t live = update_and_get_progress_history(); + size_t free = _heap->free_set()->available(); + + size_t non_taxable = free * ShenandoahPacingCycleSlack / 100; + size_t taxable = free - non_taxable; + + double tax = 1.0 * live / taxable; // base tax for available free space + tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap + + restart_with(non_taxable, tax); + + log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " + "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + byte_size_in_proper_unit(live), proper_unit_for_byte_size(live), + byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), + byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), + tax); } /* @@ -134,8 +170,9 @@ restart_with(initial, tax); - log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx", - initial / M, tax); + log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial), + tax); } size_t ShenandoahPacer::update_and_get_progress_history() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPacer.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -67,6 +67,7 @@ void setup_for_mark(); void setup_for_evac(); void setup_for_updaterefs(); + void setup_for_traversal(); inline void report_mark(size_t words); inline void report_evac(size_t words); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahPassiveMode.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" + +void ShenandoahPassiveMode::initialize_flags() const { + // Do not allow concurrent cycles. + FLAG_SET_DEFAULT(ExplicitGCInvokesConcurrent, false); + FLAG_SET_DEFAULT(ShenandoahImplicitGCInvokesConcurrent, false); + + // Passive runs with max speed, reacts on allocation failure. + FLAG_SET_DEFAULT(ShenandoahPacing, false); + + // No need for evacuation reserve with Full GC, only for Degenerated GC. + if (!ShenandoahDegeneratedGC) { + SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahEvacReserve, 0); + } + + // Disable known barriers by default. + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahLoadRefBarrier); + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier); + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahKeepAliveBarrier); + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValEnqueueBarrier); + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier); + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier); + + // Final configuration checks + // No barriers are required to run. +} +ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics() const { + if (ShenandoahGCHeuristics != NULL) { + return new ShenandoahPassiveHeuristics(); + } + ShouldNotReachHere(); + return NULL; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP + +#include "gc_implementation/shenandoah/shenandoahNormalMode.hpp" + +class ShenandoahPassiveMode : public ShenandoahNormalMode { +public: + virtual void initialize_flags() const; + virtual ShenandoahHeuristics* initialize_heuristics() const; +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -84,6 +84,10 @@ guarantee(phase == init_evac || phase == scan_roots || phase == update_roots || + phase == init_traversal_gc_work || + phase == init_weak_traversal_gc_work || + phase == final_traversal_gc_work || + phase == final_traversal_update_roots || phase == final_update_refs_roots || phase == full_gc_roots || phase == degen_gc_update_roots || diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahPhaseTimings.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -95,8 +95,10 @@ f(purge_cldg, " CLDG") \ f(purge_string_dedup, " String Dedup") \ f(complete_liveness, " Complete Liveness") \ + f(retire_tlabs, " Retire TLABs") \ + f(sync_pinned, " Sync Pinned") \ + f(trash_cset, " Trash CSet") \ f(prepare_evac, " Prepare Evacuation") \ - f(recycle_regions, " Recycle regions") \ \ /* Per-thread timer block, should have "roots" counters in consistent order */ \ f(init_evac, " Initial Evacuation") \ @@ -117,9 +119,12 @@ \ f(final_evac_gross, "Pause Final Evac (G)") \ f(final_evac, "Pause Final Evac (N)") \ + f(final_evac_retire_gclabs, " Retire GCLABs") \ \ f(init_update_refs_gross, "Pause Init Update Refs (G)") \ f(init_update_refs, "Pause Init Update Refs (N)") \ + f(init_update_refs_retire_gclabs, " Retire GCLABs") \ + f(init_update_refs_prepare, " Prepare") \ \ f(final_update_refs_gross, "Pause Final Update Refs (G)") \ f(final_update_refs, "Pause Final Update Refs (N)") \ @@ -142,7 +147,8 @@ f(final_update_refs_string_dedup_roots, " UR: String Dedup Roots") \ f(final_update_refs_finish_queues, " UR: Finish Queues") \ \ - f(final_update_refs_recycle, " Recycle") \ + f(final_update_refs_sync_pinned, " Sync Pinned") \ + f(final_update_refs_trash_cset, " Trash CSet") \ \ f(degen_gc_gross, "Pause Degenerated GC (G)") \ f(degen_gc, "Pause Degenerated GC (N)") \ @@ -164,6 +170,89 @@ f(degen_gc_update_string_dedup_roots, " DU: String Dedup Roots") \ f(degen_gc_update_finish_queues, " DU: Finish Queues") \ \ + f(init_traversal_gc_gross, "Pause Init Traversal (G)") \ + f(init_traversal_gc, "Pause Init Traversal (N)") \ + f(traversal_gc_prepare, " Prepare") \ + f(traversal_gc_accumulate_stats, " Accumulate Stats") \ + f(traversal_gc_make_parsable, " Make Parsable") \ + f(traversal_gc_resize_tlabs, " Resize TLABs") \ + f(traversal_gc_prepare_sync_pinned, " Sync Pinned") \ + \ + /* Per-thread timer block, should have "roots" counters in consistent order */ \ + f(init_traversal_gc_work, " Work") \ + f(init_traversal_gc_thread_roots, " TI: Thread Roots") \ + f(init_traversal_gc_code_roots, " TI: Code Cache Roots") \ + f(init_traversal_gc_string_table_roots, " TI: String Table Roots") \ + f(init_traversal_gc_universe_roots, " TI: Universe Roots") \ + f(init_traversal_gc_jni_roots, " TI: JNI Roots") \ + f(init_traversal_gc_jni_weak_roots, " TI: JNI Weak Roots") \ + f(init_traversal_gc_synchronizer_roots, " TI: Synchronizer Roots") \ + f(init_traversal_gc_management_roots, " TI: Management Roots") \ + f(init_traversal_gc_system_dict_roots, " TI: System Dict Roots") \ + f(init_traversal_gc_cldg_roots, " TI: CLDG Roots") \ + f(init_traversal_gc_jvmti_roots, " TI: JVMTI Roots") \ + f(init_traversal_gc_string_dedup_table_roots, " TI: Dedup Table Roots") \ + f(init_traversal_gc_string_dedup_queue_roots, " TI: Dedup Queue Roots") \ + f(init_traversal_gc_finish_queues, " TI: Finish Queues") \ + \ + /* Per-thread timer block, should have "roots" counters in consistent order */ \ + f(init_weak_traversal_gc_work, " Weak") \ + f(init_weak_traversal_gc_thread_roots, " TW: Thread Roots") \ + f(init_weak_traversal_gc_code_roots, " TW: Code Cache Roots") \ + f(init_weak_traversal_gc_string_table_roots, " TW: String Table Roots") \ + f(init_weak_traversal_gc_universe_roots, " TW: Universe Roots") \ + f(init_weak_traversal_gc_jni_roots, " TW: JNI Roots") \ + f(init_weak_traversal_gc_jni_weak_roots, " TW: JNI Weak Roots") \ + f(init_weak_traversal_gc_synchronizer_roots, " TW: Synchronizer Roots") \ + f(init_weak_traversal_gc_management_roots, " TW: Management Roots") \ + f(init_weak_traversal_gc_system_dict_roots, " TW: System Dict Roots") \ + f(init_weak_traversal_gc_cldg_roots, " TW: CLDG Roots") \ + f(init_weak_traversal_gc_jvmti_roots, " TW: JVMTI Roots") \ + f(init_weak_traversal_gc_string_dedup_table_roots, " TW: Dedup Table Roots") \ + f(init_weak_traversal_gc_string_dedup_queue_roots, " TW: Dedup Queue Roots") \ + f(init_weak_traversal_gc_finish_queues, " TW: Finish Queues") \ + \ + f(final_traversal_gc_gross, "Pause Final Traversal (G)") \ + f(final_traversal_gc, "Pause Final Traversal (N)") \ + \ + /* Per-thread timer block, should have "roots" counters in consistent order */ \ + f(final_traversal_gc_work, " Work") \ + f(final_traversal_gc_thread_roots, " TF: Thread Roots") \ + f(final_traversal_gc_code_roots, " TF: Code Cache Roots") \ + f(final_traversal_gc_string_table_roots, " TF: String Table Roots") \ + f(final_traversal_gc_universe_roots, " TF: Universe Roots") \ + f(final_traversal_gc_jni_roots, " TF: JNI Roots") \ + f(final_traversal_gc_jni_weak_roots, " TF: JNI Weak Roots") \ + f(final_traversal_gc_synchronizer_roots, " TF: Synchronizer Roots") \ + f(final_traversal_gc_management_roots, " TF: Management Roots") \ + f(final_traversal_gc_system_dict_roots, " TF: System Dict Roots") \ + f(final_traversal_gc_cldg_roots, " TF: CLDG Roots") \ + f(final_traversal_gc_jvmti_roots, " TF: JVMTI Roots") \ + f(final_traversal_gc_string_dedup_table_roots, " TF: Dedup Table Roots") \ + f(final_traversal_gc_string_dedup_queue_roots, " TF: Dedup Queue Roots") \ + f(final_traversal_gc_finish_queues, " TF: Finish Queues") \ + f(final_traversal_gc_termination, " TF: Termination") \ + \ + /* Per-thread timer block, should have "roots" counters in consistent order */ \ + f(final_traversal_update_roots, " Update Roots") \ + f(final_traversal_update_thread_roots, " TU: Thread Roots") \ + f(final_traversal_update_code_roots, " TU: Code Cache Roots") \ + f(final_traversal_update_string_table_roots, " TU: String Table Roots") \ + f(final_traversal_update_universe_roots, " TU: Universe Roots") \ + f(final_traversal_update_jni_roots, " TU: JNI Roots") \ + f(final_traversal_update_jni_weak_roots, " TU: JNI Weak Roots") \ + f(final_traversal_update_synchronizer_roots, " TU: Synchronizer Roots") \ + f(final_traversal_update_management_roots, " TU: Management Roots") \ + f(final_traversal_update_system_dict_roots, " TU: System Dict Roots") \ + f(final_traversal_update_cldg_roots, " TU: CLDG Roots") \ + f(final_traversal_update_jvmti_roots, " TU: JVMTI Roots") \ + f(final_traversal_update_string_dedup_table_roots, " TU: Dedup Table Roots") \ + f(final_traversal_update_string_dedup_queue_roots, " TU: Dedup Queue Roots") \ + f(final_traversal_update_finish_queues, " TU: Finish Queues") \ + \ + f(traversal_gc_sync_pinned, " Sync Pinned") \ + f(traversal_gc_cleanup, " Cleanup") \ + \ f(full_gc_gross, "Pause Full GC (G)") \ f(full_gc, "Pause Full GC (N)") \ f(full_gc_heapdumps, " Heap Dumps") \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -93,7 +93,6 @@ } void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops, - OopClosure* weak_oops, CLDClosure* clds, CLDClosure* weak_clds, CodeBlobClosure* blobs, @@ -101,13 +100,12 @@ uint worker_id) { assert(thread_cl == NULL, "not implemented yet"); process_java_roots(oops, clds, clds, weak_clds, blobs, worker_id); - process_vm_roots(oops, NULL, weak_oops, worker_id); + process_vm_roots(oops, NULL, NULL, worker_id); _process_strong_tasks->all_tasks_completed(); } void ShenandoahRootProcessor::process_all_roots(OopClosure* oops, - OopClosure* weak_oops, CLDClosure* clds, CodeBlobClosure* blobs, ThreadClosure* thread_cl, @@ -116,7 +114,7 @@ assert(thread_cl == NULL, "not implemented yet"); ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); process_java_roots(oops, NULL, clds, clds, NULL, worker_id); - process_vm_roots(oops, oops, weak_oops, worker_id); + process_vm_roots(oops, oops, oops, worker_id); if (blobs != NULL) { ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id); @@ -212,10 +210,15 @@ _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)), _srs(heap, true), _phase(phase), - _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()) + _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()), + _om_iterator(ShenandoahSynchronizerIterator()) { heap->set_par_threads(n_workers); heap->phase_timings()->record_workers_start(_phase); + + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStringDedup::clear_claimed(); + } } ShenandoahRootEvacuator::~ShenandoahRootEvacuator() { @@ -244,11 +247,17 @@ // in another VMOperation. oop pll = java_lang_ref_Reference::pending_list_lock(); - oopDesc::bs()->write_barrier(pll); + ((ShenandoahBarrierSet*)oopDesc::bs())->load_reference_barrier(pll); } ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); { + CLDToOopClosure clds(oops); + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id); + _cld_iterator.root_cld_do(&clds, &clds); + } + + { ResourceMark rm; ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id); Threads::possibly_parallel_oops_do(oops, NULL, NULL); @@ -259,10 +268,68 @@ _coderoots_cset_iterator.possibly_parallel_blobs_do(blobs); } - if (_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_jvmti_oops_do)) { - ShenandoahForwardedIsAliveClosure is_alive; + // if (ShenandoahStringDedup::is_enabled()) { + // ShenandoahForwardedIsAliveClosure is_alive; + // ShenandoahStringDedup::parallel_oops_do(&is_alive, oops, worker_id); + // } + + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_Universe_oops_do)) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id); + Universe::oops_do(oops); + } + + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_JNIHandles_oops_do)) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id); + JNIHandles::oops_do(oops); + } + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_FlatProfiler_oops_do)) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::FlatProfilerRoots, worker_id); + FlatProfiler::oops_do(oops); + } + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_Management_oops_do)) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id); + Management::oops_do(oops); + } + + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_jvmti_oops_do)) { ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id); + JvmtiExport::oops_do(oops); + // In JDK 8, this is handled by JNIHandles::weak_oops_do. We cannot enter here, because + // it would walk the JvmtiTagMap twice (which is okay) and possibly by multiple threads + // (which is not okay, because that walk is not thread-safe). In subsequent releases, + // it is handled in a more straightforward manner, see JDK-8189360. + /* + ShenandoahForwardedIsAliveClosure is_alive; JvmtiExport::weak_oops_do(&is_alive, oops); + */ + } + + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_SystemDictionary_oops_do)) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id); + SystemDictionary::oops_do(oops); + } + + if (!_evacuation_tasks->is_task_claimed(SHENANDOAH_EVAC_JNIHandles_weak_oops_do)) { + AlwaysTrueClosure always_true; + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id); + JNIHandles::weak_oops_do(&always_true, oops); + } + + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringDedupRoots, worker_id); + ShenandoahStringDedup::parallel_oops_do(oops); + } + + { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id); + while(_om_iterator.parallel_oops_do(oops)); + } + + // All threads execute the following. A specific chunk of buckets + // from the StringTable are the individual tasks. + { + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id); + StringTable::possibly_parallel_oops_do(oops); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -77,7 +77,7 @@ ~ShenandoahRootProcessor(); // Apply oops, clds and blobs to all strongly reachable roots in the system - void process_strong_roots(OopClosure* oops, OopClosure* weak_oops, + void process_strong_roots(OopClosure* oops, CLDClosure* clds, CLDClosure* weak_clds, CodeBlobClosure* blobs, @@ -85,7 +85,7 @@ uint worker_id); // Apply oops, clds and blobs to strongly and weakly reachable roots in the system - void process_all_roots(OopClosure* oops, OopClosure* weak_oops, + void process_all_roots(OopClosure* oops, CLDClosure* clds, CodeBlobClosure* blobs, ThreadClosure* thread_cl, @@ -102,9 +102,17 @@ SubTasksDone* _evacuation_tasks; SharedHeap::StrongRootsScope _srs; ShenandoahPhaseTimings::Phase _phase; + ParallelCLDRootIterator _cld_iterator; ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator; + ShenandoahSynchronizerIterator _om_iterator; enum Shenandoah_evacuate_roots_tasks { + SHENANDOAH_EVAC_Universe_oops_do, + SHENANDOAH_EVAC_JNIHandles_oops_do, + SHENANDOAH_EVAC_JNIHandles_weak_oops_do, + SHENANDOAH_EVAC_FlatProfiler_oops_do, + SHENANDOAH_EVAC_Management_oops_do, + SHENANDOAH_EVAC_SystemDictionary_oops_do, SHENANDOAH_EVAC_jvmti_oops_do, // Leave this one last. SHENANDOAH_EVAC_NumElements diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahRuntime.hpp" +#include "runtime/interfaceSupport.hpp" +#include "oops/oop.inline.hpp" + +void ShenandoahRuntime::write_ref_array_pre_oop_entry(oop* dst, size_t length) { + ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); + assert(length <= INT_MAX, err_msg("sanity: " SIZE_FORMAT, length)); + bs->write_ref_array_pre(dst, (int)length, false); +} + +void ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry(narrowOop* dst, size_t length) { + ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); + assert(length <= INT_MAX, err_msg("sanity: " SIZE_FORMAT, length)); + bs->write_ref_array_pre(dst, (int)length, false); +} + +void ShenandoahRuntime::write_ref_array_post_entry(HeapWord* dst, size_t length) { + ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); + bs->ShenandoahBarrierSet::write_ref_array(dst, length); +} + +// Shenandoah pre write barrier slowpath +JRT_LEAF(void, ShenandoahRuntime::write_ref_field_pre_entry(oopDesc* orig, JavaThread *thread)) + if (orig == NULL) { + assert(false, "should be optimized out"); + return; + } + shenandoah_assert_correct(NULL, orig); + // store the original value that was in the field reference + assert(thread->satb_mark_queue().is_active(), "Shouldn't be here otherwise"); + thread->satb_mark_queue().enqueue_known_active(orig); +JRT_END + +JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_JRT(oopDesc* src)) + oop result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_mutator(oop(src)); + return (oopDesc*) result; +JRT_END + +IRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_interpreter(oopDesc* src)) + oop result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(oop(src)); + return (oopDesc*) result; +IRT_END + +// Shenandoah clone barrier: makes sure that references point to to-space +// in cloned objects. +JRT_LEAF(void, ShenandoahRuntime::shenandoah_clone_barrier(oopDesc* obj)) + ShenandoahBarrierSet::barrier_set()->write_region(MemRegion((HeapWord*) obj, obj->size())); +JRT_END diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP + +#include "memory/allocation.hpp" +#include "oops/oopsHierarchy.hpp" + +class HeapWord; +class JavaThread; +class oopDesc; + +class ShenandoahRuntime : public AllStatic { +public: + static void write_ref_array_pre_oop_entry(oop* dst, size_t length); + static void write_ref_array_pre_narrow_oop_entry(narrowOop* dst, size_t length); + static void write_ref_array_post_entry(HeapWord* dst, size_t length); + static void write_ref_field_pre_entry(oopDesc* orig, JavaThread* thread); + + static oopDesc* load_reference_barrier_JRT(oopDesc* src); + static oopDesc* load_reference_barrier_interpreter(oopDesc* src); + + static void shenandoah_clone_barrier(oopDesc* obj); +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -151,7 +151,7 @@ _rehash_needed = true; } - if (oopDesc::equals(existing_value, value)) { + if (existing_value == value) { return false; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStrDedupTable.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -82,7 +82,7 @@ private: static bool equals(typeArrayOop value1, typeArrayOop value2) { - return (oopDesc::equals(value1, value2) || + return (value1 == value2 || (value1->length() == value2->length() && (!memcmp(value1->base(T_CHAR), value2->base(T_CHAR), diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStringDedup.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStringDedup.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStringDedup.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahStringDedup.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahCollectionSet.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,2999 @@ +/* + * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" +#include "gc_implementation/shenandoah/shenandoahRuntime.hpp" +#include "opto/block.hpp" +#include "opto/callnode.hpp" +#include "opto/phaseX.hpp" +#include "opto/rootnode.hpp" +#include "opto/runtime.hpp" +#include "opto/subnode.hpp" + +#ifdef _LP64 +#define LoadXNode LoadLNode +#else +#define LoadXNode LoadINode +#endif + +bool ShenandoahBarrierC2Support::expand(Compile* C, PhaseIterGVN& igvn) { + if (C->shenandoah_barriers_count() > 0) { + C->clear_major_progress(); + PhaseIdealLoop ideal_loop(igvn, false, true); + if (C->failing()) return false; + PhaseIdealLoop::verify(igvn); + DEBUG_ONLY(verify_raw_mem(C->root());) + } + return true; +} + +bool ShenandoahBarrierC2Support::is_heap_state_test(Node* iff, int mask) { + if (!UseShenandoahGC) { + return false; + } + assert(iff->is_If(), "bad input"); + if (iff->Opcode() != Op_If) { + return false; + } + Node* bol = iff->in(1); + if (!bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::ne) { + return false; + } + Node* cmp = bol->in(1); + if (cmp->Opcode() != Op_CmpI) { + return false; + } + Node* in1 = cmp->in(1); + Node* in2 = cmp->in(2); + if (in2->find_int_con(-1) != 0) { + return false; + } + if (in1->Opcode() != Op_AndI) { + return false; + } + in2 = in1->in(2); + if (in2->find_int_con(-1) != mask) { + return false; + } + in1 = in1->in(1); + + return is_gc_state_load(in1); +} + +bool ShenandoahBarrierC2Support::is_heap_stable_test(Node* iff) { + return is_heap_state_test(iff, ShenandoahHeap::HAS_FORWARDED); +} + +bool ShenandoahBarrierC2Support::is_gc_state_load(Node *n) { + if (!UseShenandoahGC) { + return false; + } + if (n->Opcode() != Op_LoadB && n->Opcode() != Op_LoadUB) { + return false; + } + Node* addp = n->in(MemNode::Address); + if (!addp->is_AddP()) { + return false; + } + Node* base = addp->in(AddPNode::Address); + Node* off = addp->in(AddPNode::Offset); + if (base->Opcode() != Op_ThreadLocal) { + return false; + } + if (off->find_intptr_t_con(-1) != in_bytes(JavaThread::gc_state_offset())) { + return false; + } + return true; +} + +bool ShenandoahBarrierC2Support::has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase) { + assert(phase->is_dominator(stop, start), "bad inputs"); + ResourceMark rm; + Unique_Node_List wq; + wq.push(start); + for (uint next = 0; next < wq.size(); next++) { + Node *m = wq.at(next); + if (m == stop) { + continue; + } + if (m->is_SafePoint() && !m->is_CallLeaf()) { + return true; + } + if (m->is_Region()) { + for (uint i = 1; i < m->req(); i++) { + wq.push(m->in(i)); + } + } else { + wq.push(m->in(0)); + } + } + return false; +} + +bool ShenandoahBarrierC2Support::try_common_gc_state_load(Node *n, PhaseIdealLoop *phase) { + assert(is_gc_state_load(n), "inconsistent"); + Node* addp = n->in(MemNode::Address); + Node* dominator = NULL; + for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { + Node* u = addp->fast_out(i); + assert(is_gc_state_load(u), "inconsistent"); + if (u != n && phase->is_dominator(u->in(0), n->in(0))) { + if (dominator == NULL) { + dominator = u; + } else { + if (phase->dom_depth(u->in(0)) < phase->dom_depth(dominator->in(0))) { + dominator = u; + } + } + } + } + if (dominator == NULL || has_safepoint_between(n->in(0), dominator->in(0), phase)) { + return false; + } + phase->igvn().replace_node(n, dominator); + + return true; +} + +#ifdef ASSERT +bool ShenandoahBarrierC2Support::verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used) { + assert(phis.size() == 0, ""); + + while (true) { + if (in->bottom_type() == TypePtr::NULL_PTR) { + if (trace) {tty->print_cr("NULL");} + } else if (!in->bottom_type()->make_ptr()->make_oopptr()) { + if (trace) {tty->print_cr("Non oop");} + } else if (in->bottom_type()->make_ptr()->make_oopptr() == TypeInstPtr::MIRROR) { + if (trace) {tty->print_cr("Java mirror");} + } else { + if (in->is_ConstraintCast() || in->Opcode() == Op_CheckCastPP) { + in = in->in(1); + continue; + } else if (in->is_AddP()) { + assert(!in->in(AddPNode::Address)->is_top(), "no raw memory access"); + in = in->in(AddPNode::Address); + continue; + } else if (in->is_Con()) { + if (trace) { + tty->print("Found constant"); + in->dump(); + } + } else if (in->Opcode() == Op_Parm) { + if (trace) { + tty->print("Found argument"); + } + } else if (in->Opcode() == Op_CreateEx) { + if (trace) { + tty->print("Found create-exception"); + } + } else if (in->Opcode() == Op_LoadP && in->adr_type() == TypeRawPtr::BOTTOM) { + if (trace) { + tty->print("Found raw LoadP (OSR argument?)"); + } + } else if (in->Opcode() == Op_ShenandoahLoadReferenceBarrier) { + if (t == ShenandoahOopStore) { + uint i = 0; + for (; i < phis.size(); i++) { + Node* n = phis.node_at(i); + } + if (i == phis.size()) { + return false; + } + } + barriers_used.push(in); + if (trace) {tty->print("Found barrier"); in->dump();} + } else if (in->is_Proj() && in->in(0)->is_Allocate()) { + if (trace) { + tty->print("Found alloc"); + in->in(0)->dump(); + } + } else if (in->is_Proj() && (in->in(0)->Opcode() == Op_CallStaticJava || in->in(0)->Opcode() == Op_CallDynamicJava)) { + if (trace) { + tty->print("Found Java call"); + } + } else if (in->is_Phi()) { + if (!visited.test_set(in->_idx)) { + if (trace) {tty->print("Pushed phi:"); in->dump();} + phis.push(in, 2); + in = in->in(1); + continue; + } + if (trace) {tty->print("Already seen phi:"); in->dump();} + } else if (in->Opcode() == Op_CMoveP || in->Opcode() == Op_CMoveN) { + if (!visited.test_set(in->_idx)) { + if (trace) {tty->print("Pushed cmovep:"); in->dump();} + phis.push(in, CMoveNode::IfTrue); + in = in->in(CMoveNode::IfFalse); + continue; + } + if (trace) {tty->print("Already seen cmovep:"); in->dump();} + } else if (in->Opcode() == Op_EncodeP || in->Opcode() == Op_DecodeN) { + in = in->in(1); + continue; + } else { + return false; + } + } + bool cont = false; + while (phis.is_nonempty()) { + uint idx = phis.index(); + Node* phi = phis.node(); + if (idx >= phi->req()) { + if (trace) {tty->print("Popped phi:"); phi->dump();} + phis.pop(); + continue; + } + if (trace) {tty->print("Next entry(%d) for phi:", idx); phi->dump();} + in = phi->in(idx); + phis.set_index(idx+1); + cont = true; + break; + } + if (!cont) { + break; + } + } + return true; +} + +void ShenandoahBarrierC2Support::report_verify_failure(const char* msg, Node* n1, Node* n2) { + if (n1 != NULL) { + n1->dump(+10); + } + if (n2 != NULL) { + n2->dump(+10); + } + fatal(err_msg("%s", msg)); +} + +static const char* call_name(CallNode* call) { + if (call->is_CallRuntime()) { + return call->as_CallRuntime()->_name; + } + if (call->is_CallStaticJava()) { + return call->as_CallStaticJava()->_name; + } + return NULL; +} + +void ShenandoahBarrierC2Support::verify(RootNode* root) { + ResourceMark rm; + Unique_Node_List wq; + GrowableArray barriers; + Unique_Node_List barriers_used; + Node_Stack phis(0); + VectorSet visited(Thread::current()->resource_area()); + const bool trace = true; + const bool verify_no_useless_barrier = false; + + wq.push(root); + for (uint next = 0; next < wq.size(); next++) { + Node *n = wq.at(next); + if (n->is_Load()) { + const bool trace = false; + if (trace) {tty->print("Verifying"); n->dump();} + if (n->Opcode() == Op_LoadRange || n->Opcode() == Op_LoadKlass || n->Opcode() == Op_LoadNKlass) { + if (trace) {tty->print_cr("Load range/klass");} + } else { + const TypePtr* adr_type = n->as_Load()->adr_type(); + + if (adr_type->isa_oopptr() && adr_type->is_oopptr()->offset() == oopDesc::mark_offset_in_bytes()) { + if (trace) {tty->print_cr("Mark load");} + } else if (adr_type->isa_instptr() && + adr_type->is_instptr()->klass()->is_subtype_of(Compile::current()->env()->Reference_klass()) && + adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset) { + if (trace) {tty->print_cr("Reference.get()");} + } else if (!verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahLoad, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: Load should have barriers", n); + } + } + } else if (n->is_Store()) { + const bool trace = false; + + if (trace) {tty->print("Verifying"); n->dump();} + if (n->in(MemNode::ValueIn)->bottom_type()->make_oopptr()) { + Node* adr = n->in(MemNode::Address); + bool verify = true; + + if (adr->is_AddP() && adr->in(AddPNode::Base)->is_top()) { + adr = adr->in(AddPNode::Address); + if (adr->is_AddP()) { + assert(adr->in(AddPNode::Base)->is_top(), ""); + adr = adr->in(AddPNode::Address); + if (adr->Opcode() == Op_LoadP && + adr->in(MemNode::Address)->in(AddPNode::Base)->is_top() && + adr->in(MemNode::Address)->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && + adr->in(MemNode::Address)->in(AddPNode::Offset)->find_intptr_t_con(-1) == in_bytes(JavaThread::satb_mark_queue_offset()) + in_bytes(PtrQueue::byte_offset_of_buf())) { + if (trace) {tty->print_cr("SATB prebarrier");} + verify = false; + } + } + } + + if (verify && !verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahValue, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: Store should have barriers", n); + } + } + if (!verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: Store (address) should have barriers", n); + } + } else if (n->Opcode() == Op_CmpP) { + const bool trace = false; + + Node* in1 = n->in(1); + Node* in2 = n->in(2); + if (in1->bottom_type()->isa_oopptr()) { + if (trace) {tty->print("Verifying"); n->dump();} + + bool mark_inputs = false; + if (in1->bottom_type() == TypePtr::NULL_PTR || in2->bottom_type() == TypePtr::NULL_PTR || + (in1->is_Con() || in2->is_Con())) { + if (trace) {tty->print_cr("Comparison against a constant");} + mark_inputs = true; + } else if ((in1->is_CheckCastPP() && in1->in(1)->is_Proj() && in1->in(1)->in(0)->is_Allocate()) || + (in2->is_CheckCastPP() && in2->in(1)->is_Proj() && in2->in(1)->in(0)->is_Allocate())) { + if (trace) {tty->print_cr("Comparison with newly alloc'ed object");} + mark_inputs = true; + } else { + assert(in2->bottom_type()->isa_oopptr(), ""); + + if (!verify_helper(in1, phis, visited, ShenandoahStore, trace, barriers_used) || + !verify_helper(in2, phis, visited, ShenandoahStore, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: Cmp should have barriers", n); + } + } + if (verify_no_useless_barrier && + mark_inputs && + (!verify_helper(in1, phis, visited, ShenandoahValue, trace, barriers_used) || + !verify_helper(in2, phis, visited, ShenandoahValue, trace, barriers_used))) { + phis.clear(); + visited.Reset(); + } + } + } else if (n->is_LoadStore()) { + if (n->in(MemNode::ValueIn)->bottom_type()->make_ptr() && + !verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahValue, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: LoadStore (value) should have barriers", n); + } + + if (n->in(MemNode::Address)->bottom_type()->make_oopptr() && !verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: LoadStore (address) should have barriers", n); + } + } else if (n->Opcode() == Op_CallLeafNoFP || n->Opcode() == Op_CallLeaf) { + CallNode* call = n->as_Call(); + + static struct { + const char* name; + struct { + int pos; + verify_type t; + } args[6]; + } calls[] = { + "aescrypt_encryptBlock", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "aescrypt_decryptBlock", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "multiplyToLen", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { TypeFunc::Parms+4, ShenandoahStore }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "squareToLen", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "montgomery_multiply", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, + { TypeFunc::Parms+6, ShenandoahStore }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "montgomery_square", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+5, ShenandoahStore }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "mulAdd", + { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "vectorizedMismatch", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "updateBytesCRC32", + { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "updateBytesAdler32", + { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "updateBytesCRC32C", + { { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahLoad}, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "counterMode_AESCrypt", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, + { TypeFunc::Parms+3, ShenandoahStore }, { TypeFunc::Parms+5, ShenandoahStore }, { TypeFunc::Parms+6, ShenandoahStore } }, + "cipherBlockChaining_encryptAESCrypt", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, + { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "cipherBlockChaining_decryptAESCrypt", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, + { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "shenandoah_clone_barrier", + { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "ghash_processBlocks", + { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha1_implCompress", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha256_implCompress", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha512_implCompress", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha1_implCompressMB", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha256_implCompressMB", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "sha512_implCompressMB", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + "encodeBlock", + { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahStore }, { -1, ShenandoahNone }, + { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, + }; + + if (call->is_CallRuntime() && call->as_CallRuntime()->is_call_to_arraycopystub()) { + Node* dest = NULL; + const TypeTuple* args = n->as_Call()->_tf->domain(); + for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) { + if (args->field_at(i)->isa_ptr()) { + j++; + if (j == 2) { + dest = n->in(i); + break; + } + } + } + if (!verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahLoad, trace, barriers_used) || + !verify_helper(dest, phis, visited, ShenandoahStore, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: ArrayCopy should have barriers", n); + } + } else if (strlen(call_name(call)) > 5 && + !strcmp(call_name(call) + strlen(call_name(call)) - 5, "_fill")) { + if (!verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahStore, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: _fill should have barriers", n); + } + } else if (!strcmp(call_name(call), "g1_wb_pre")) { + // skip + } else { + const int calls_len = sizeof(calls) / sizeof(calls[0]); + int i = 0; + for (; i < calls_len; i++) { + if (!strcmp(calls[i].name, call_name(call))) { + break; + } + } + if (i != calls_len) { + const uint args_len = sizeof(calls[0].args) / sizeof(calls[0].args[0]); + for (uint j = 0; j < args_len; j++) { + int pos = calls[i].args[j].pos; + if (pos == -1) { + break; + } + if (!verify_helper(call->in(pos), phis, visited, calls[i].args[j].t, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); + } + } + for (uint j = TypeFunc::Parms; j < call->req(); j++) { + if (call->in(j)->bottom_type()->make_ptr() && + call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { + uint k = 0; + for (; k < args_len && calls[i].args[k].pos != (int)j; k++); + if (k == args_len) { + fatal(err_msg("arg %d for call %s not covered", j, call_name(call))); + } + } + } + } else { + for (uint j = TypeFunc::Parms; j < call->req(); j++) { + if (call->in(j)->bottom_type()->make_ptr() && + call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { + fatal(err_msg("%s not covered", call_name(call))); + } + } + } + } + } else if (n->Opcode() == Op_ShenandoahLoadReferenceBarrier) { + // skip + } else if (n->is_AddP() + || n->is_Phi() + || n->is_ConstraintCast() + || n->Opcode() == Op_CheckCastPP + || n->Opcode() == Op_Return + || n->Opcode() == Op_CMoveP + || n->Opcode() == Op_CMoveN + || n->Opcode() == Op_Rethrow + || n->is_MemBar() + || n->Opcode() == Op_Conv2B + || n->Opcode() == Op_SafePoint + || n->is_CallJava() + || n->Opcode() == Op_Unlock + || n->Opcode() == Op_EncodeP + || n->Opcode() == Op_DecodeN) { + // nothing to do + } else { + static struct { + int opcode; + struct { + int pos; + verify_type t; + } inputs[2]; + } others[] = { + Op_FastLock, + { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, + Op_Lock, + { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone} }, + Op_AryEq, + { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, + Op_StrIndexOf, + { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, + Op_StrComp, + { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, + Op_StrEquals, + { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, + Op_EncodeISOArray, + { { 2, ShenandoahLoad }, { 3, ShenandoahStore } }, + Op_CastP2X, + { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, + Op_ClearArray, + { { 3, ShenandoahStore }, { -1, ShenandoahNone} }, + }; + + const int others_len = sizeof(others) / sizeof(others[0]); + int i = 0; + for (; i < others_len; i++) { + if (others[i].opcode == n->Opcode()) { + break; + } + } + uint stop = n->is_Call() ? n->as_Call()->tf()->domain()->cnt() : n->req(); + if (i != others_len) { + const uint inputs_len = sizeof(others[0].inputs) / sizeof(others[0].inputs[0]); + for (uint j = 0; j < inputs_len; j++) { + int pos = others[i].inputs[j].pos; + if (pos == -1) { + break; + } + if (!verify_helper(n->in(pos), phis, visited, others[i].inputs[j].t, trace, barriers_used)) { + report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); + } + } + for (uint j = 1; j < stop; j++) { + if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && + n->in(j)->bottom_type()->make_ptr()->make_oopptr()) { + uint k = 0; + for (; k < inputs_len && others[i].inputs[k].pos != (int)j; k++); + if (k == inputs_len) { + fatal(err_msg("arg %d for node %s not covered", j, n->Name())); + } + } + } + } else { + for (uint j = 1; j < stop; j++) { + if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && + n->in(j)->bottom_type()->make_ptr()->make_oopptr()) { + fatal(err_msg("%s not covered", n->Name())); + } + } + } + } + + if (n->is_SafePoint()) { + SafePointNode* sfpt = n->as_SafePoint(); + if (verify_no_useless_barrier && sfpt->jvms() != NULL) { + for (uint i = sfpt->jvms()->scloff(); i < sfpt->jvms()->endoff(); i++) { + if (!verify_helper(sfpt->in(i), phis, visited, ShenandoahLoad, trace, barriers_used)) { + phis.clear(); + visited.Reset(); + } + } + } + } + } + + if (verify_no_useless_barrier) { + for (int i = 0; i < barriers.length(); i++) { + Node* n = barriers.at(i); + if (!barriers_used.member(n)) { + tty->print("XXX useless barrier"); n->dump(-2); + ShouldNotReachHere(); + } + } + } +} +#endif + +bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase) { + // That both nodes have the same control is not sufficient to prove + // domination, verify that there's no path from d to n + ResourceMark rm; + Unique_Node_List wq; + wq.push(d); + for (uint next = 0; next < wq.size(); next++) { + Node *m = wq.at(next); + if (m == n) { + return false; + } + if (m->is_Phi() && m->in(0)->is_Loop()) { + assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control"); + } else { + for (uint i = 0; i < m->req(); i++) { + if (m->in(i) != NULL && phase->ctrl_or_self(m->in(i)) == c) { + wq.push(m->in(i)); + } + } + } + } + return true; +} + +bool ShenandoahBarrierC2Support::is_dominator(Node* d_c, Node* n_c, Node* d, Node* n, PhaseIdealLoop* phase) { + if (d_c != n_c) { + return phase->is_dominator(d_c, n_c); + } + return is_dominator_same_ctrl(d_c, d, n, phase); +} + +Node* next_mem(Node* mem, int alias) { + Node* res = NULL; + if (mem->is_Proj()) { + res = mem->in(0); + } else if (mem->is_SafePoint() || mem->is_MemBar()) { + res = mem->in(TypeFunc::Memory); + } else if (mem->is_Phi()) { + res = mem->in(1); + } else if (mem->is_MergeMem()) { + res = mem->as_MergeMem()->memory_at(alias); + } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { + assert(alias = Compile::AliasIdxRaw, "following raw memory can't lead to a barrier"); + res = mem->in(MemNode::Memory); + } else { +#ifdef ASSERT + mem->dump(); +#endif + ShouldNotReachHere(); + } + return res; +} + +Node* ShenandoahBarrierC2Support::no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase) { + Node* iffproj = NULL; + while (c != dom) { + Node* next = phase->idom(c); + assert(next->unique_ctrl_out() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?"); + if (c->is_Region()) { + ResourceMark rm; + Unique_Node_List wq; + wq.push(c); + for (uint i = 0; i < wq.size(); i++) { + Node *n = wq.at(i); + if (n == next) { + continue; + } + if (n->is_Region()) { + for (uint j = 1; j < n->req(); j++) { + wq.push(n->in(j)); + } + } else { + wq.push(n->in(0)); + } + } + for (uint i = 0; i < wq.size(); i++) { + Node *n = wq.at(i); + assert(n->is_CFG(), ""); + if (n->is_Multi()) { + for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { + Node* u = n->fast_out(j); + if (u->is_CFG()) { + if (!wq.member(u) && !u->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) { + return NodeSentinel; + } + } + } + } + } + } else if (c->is_Proj()) { + if (c->is_IfProj()) { + if (c->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) != NULL) { + // continue; + } else { + if (!allow_one_proj) { + return NodeSentinel; + } + if (iffproj == NULL) { + iffproj = c; + } else { + return NodeSentinel; + } + } + } else if (c->Opcode() == Op_JumpProj) { + return NodeSentinel; // unsupported + } else if (c->Opcode() == Op_CatchProj) { + return NodeSentinel; // unsupported + } else if (c->Opcode() == Op_CProj && next->Opcode() == Op_NeverBranch) { + return NodeSentinel; // unsupported + } else { + assert(next->unique_ctrl_out() == c, "unsupported branch pattern"); + } + } + c = next; + } + return iffproj; +} + +Node* ShenandoahBarrierC2Support::dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase) { + ResourceMark rm; + VectorSet wq(Thread::current()->resource_area()); + wq.set(mem->_idx); + mem_ctrl = phase->ctrl_or_self(mem); + while (!phase->is_dominator(mem_ctrl, ctrl) || mem_ctrl == ctrl) { + mem = next_mem(mem, alias); + if (wq.test_set(mem->_idx)) { + return NULL; + } + mem_ctrl = phase->ctrl_or_self(mem); + } + if (mem->is_MergeMem()) { + mem = mem->as_MergeMem()->memory_at(alias); + mem_ctrl = phase->ctrl_or_self(mem); + } + return mem; +} + +Node* ShenandoahBarrierC2Support::find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase) { + Node* mem = NULL; + Node* c = ctrl; + do { + if (c->is_Region()) { + Node* phi_bottom = NULL; + for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax && mem == NULL; i++) { + Node* u = c->fast_out(i); + if (u->is_Phi() && u->bottom_type() == Type::MEMORY) { + if (u->adr_type() == TypePtr::BOTTOM) { + mem = u; + } + } + } + } else { + if (c->is_Call() && c->as_Call()->adr_type() != NULL) { + CallProjections projs; + c->as_Call()->extract_projections(&projs, true, false); + if (projs.fallthrough_memproj != NULL) { + if (projs.fallthrough_memproj->adr_type() == TypePtr::BOTTOM) { + if (projs.catchall_memproj == NULL) { + mem = projs.fallthrough_memproj; + } else { + if (phase->is_dominator(projs.fallthrough_catchproj, ctrl)) { + mem = projs.fallthrough_memproj; + } else { + assert(phase->is_dominator(projs.catchall_catchproj, ctrl), "one proj must dominate barrier"); + mem = projs.catchall_memproj; + } + } + } + } else { + Node* proj = c->as_Call()->proj_out(TypeFunc::Memory); + if (proj != NULL && + proj->adr_type() == TypePtr::BOTTOM) { + mem = proj; + } + } + } else { + for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { + Node* u = c->fast_out(i); + if (u->is_Proj() && + u->bottom_type() == Type::MEMORY && + u->adr_type() == TypePtr::BOTTOM) { + assert(c->is_SafePoint() || c->is_MemBar() || c->is_Start(), ""); + assert(mem == NULL, "only one proj"); + mem = u; + } + } + assert(!c->is_Call() || c->as_Call()->adr_type() != NULL || mem == NULL, "no mem projection expected"); + } + } + c = phase->idom(c); + } while (mem == NULL); + return mem; +} + +void ShenandoahBarrierC2Support::follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase) { + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* u = n->fast_out(i); + if (!u->is_CFG() && phase->get_ctrl(u) == ctrl && (!u->is_Phi() || !u->in(0)->is_Loop() || u->in(LoopNode::LoopBackControl) != n)) { + uses.push(u); + } + } +} + +void ShenandoahBarrierC2Support::test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, + PhaseIdealLoop* phase) { + IdealLoopTree* loop = phase->get_loop(ctrl); + Node* thread = new (phase->C) ThreadLocalNode(); + phase->register_new_node(thread, ctrl); + Node* offset = phase->igvn().MakeConX(in_bytes(JavaThread::gc_state_offset())); + phase->set_ctrl(offset, phase->C->root()); + Node* gc_state_addr = new (phase->C) AddPNode(phase->C->top(), thread, offset); + phase->register_new_node(gc_state_addr, ctrl); + uint gc_state_idx = Compile::AliasIdxRaw; + const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument + debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx)); + + Node* gc_state = new (phase->C) LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); + phase->register_new_node(gc_state, ctrl); + Node* heap_stable_and = new (phase->C) AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED)); + phase->register_new_node(heap_stable_and, ctrl); + Node* heap_stable_cmp = new (phase->C) CmpINode(heap_stable_and, phase->igvn().zerocon(T_INT)); + phase->register_new_node(heap_stable_cmp, ctrl); + Node* heap_stable_test = new (phase->C) BoolNode(heap_stable_cmp, BoolTest::ne); + phase->register_new_node(heap_stable_test, ctrl); + IfNode* heap_stable_iff = new (phase->C) IfNode(ctrl, heap_stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); + phase->register_control(heap_stable_iff, loop, ctrl); + + heap_stable_ctrl = new (phase->C) IfFalseNode(heap_stable_iff); + phase->register_control(heap_stable_ctrl, loop, heap_stable_iff); + ctrl = new (phase->C) IfTrueNode(heap_stable_iff); + phase->register_control(ctrl, loop, heap_stable_iff); + + assert(is_heap_stable_test(heap_stable_iff), "Should match the shape"); +} + +void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) { + const Type* val_t = phase->igvn().type(val); + if (val_t->meet(TypePtr::NULL_PTR) == val_t) { + IdealLoopTree* loop = phase->get_loop(ctrl); + Node* null_cmp = new (phase->C) CmpPNode(val, phase->igvn().zerocon(T_OBJECT)); + phase->register_new_node(null_cmp, ctrl); + Node* null_test = new (phase->C) BoolNode(null_cmp, BoolTest::ne); + phase->register_new_node(null_test, ctrl); + IfNode* null_iff = new (phase->C) IfNode(ctrl, null_test, PROB_LIKELY(0.999), COUNT_UNKNOWN); + phase->register_control(null_iff, loop, ctrl); + ctrl = new (phase->C) IfTrueNode(null_iff); + phase->register_control(ctrl, loop, null_iff); + null_ctrl = new (phase->C) IfFalseNode(null_iff); + phase->register_control(null_ctrl, loop, null_iff); + } +} + +Node* ShenandoahBarrierC2Support::clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase) { + IdealLoopTree *loop = phase->get_loop(c); + Node* iff = unc_ctrl->in(0); + assert(iff->is_If(), "broken"); + Node* new_iff = iff->clone(); + new_iff->set_req(0, c); + phase->register_control(new_iff, loop, c); + Node* iffalse = new (phase->C) IfFalseNode(new_iff->as_If()); + phase->register_control(iffalse, loop, new_iff); + Node* iftrue = new (phase->C) IfTrueNode(new_iff->as_If()); + phase->register_control(iftrue, loop, new_iff); + c = iftrue; + const Type *t = phase->igvn().type(val); + assert(val->Opcode() == Op_CastPP, "expect cast to non null here"); + Node* uncasted_val = val->in(1); + val = new (phase->C) CastPPNode(uncasted_val, t); + val->init_req(0, c); + phase->register_new_node(val, c); + return val; +} + +void ShenandoahBarrierC2Support::fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, + Unique_Node_List& uses, PhaseIdealLoop* phase) { + IfNode* iff = unc_ctrl->in(0)->as_If(); + Node* proj = iff->proj_out(0); + assert(proj != unc_ctrl, "bad projection"); + Node* use = proj->unique_ctrl_out(); + + assert(use == unc || use->is_Region(), "what else?"); + + uses.clear(); + if (use == unc) { + phase->set_idom(use, new_unc_ctrl, phase->dom_depth(use)); + for (uint i = 1; i < unc->req(); i++) { + Node* n = unc->in(i); + if (phase->has_ctrl(n) && phase->get_ctrl(n) == proj) { + uses.push(n); + } + } + } else { + assert(use->is_Region(), "what else?"); + uint idx = 1; + for (; use->in(idx) != proj; idx++); + for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) { + Node* u = use->fast_out(i); + if (u->is_Phi() && phase->get_ctrl(u->in(idx)) == proj) { + uses.push(u->in(idx)); + } + } + } + for(uint next = 0; next < uses.size(); next++ ) { + Node *n = uses.at(next); + assert(phase->get_ctrl(n) == proj, "bad control"); + phase->set_ctrl_and_loop(n, new_unc_ctrl); + if (n->in(0) == proj) { + phase->igvn().replace_input_of(n, 0, new_unc_ctrl); + } + for (uint i = 0; i < n->req(); i++) { + Node* m = n->in(i); + if (m != NULL && phase->has_ctrl(m) && phase->get_ctrl(m) == proj) { + uses.push(m); + } + } + } + + phase->igvn().rehash_node_delayed(use); + int nb = use->replace_edge(proj, new_unc_ctrl); + assert(nb == 1, "only use expected"); +} + +void ShenandoahBarrierC2Support::in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) { + IdealLoopTree *loop = phase->get_loop(ctrl); + Node* raw_rbtrue = new (phase->C) CastP2XNode(ctrl, val); + phase->register_new_node(raw_rbtrue, ctrl); + Node* cset_offset = new (phase->C) URShiftXNode(raw_rbtrue, phase->igvn().intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint())); + phase->register_new_node(cset_offset, ctrl); + Node* in_cset_fast_test_base_addr = phase->igvn().makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr())); + phase->set_ctrl(in_cset_fast_test_base_addr, phase->C->root()); + Node* in_cset_fast_test_adr = new (phase->C) AddPNode(phase->C->top(), in_cset_fast_test_base_addr, cset_offset); + phase->register_new_node(in_cset_fast_test_adr, ctrl); + uint in_cset_fast_test_idx = Compile::AliasIdxRaw; + const TypePtr* in_cset_fast_test_adr_type = NULL; // debug-mode-only argument + debug_only(in_cset_fast_test_adr_type = phase->C->get_adr_type(in_cset_fast_test_idx)); + Node* in_cset_fast_test_load = new (phase->C) LoadBNode(ctrl, raw_mem, in_cset_fast_test_adr, in_cset_fast_test_adr_type, TypeInt::BYTE, MemNode::unordered); + phase->register_new_node(in_cset_fast_test_load, ctrl); + Node* in_cset_fast_test_cmp = new (phase->C) CmpINode(in_cset_fast_test_load, phase->igvn().zerocon(T_INT)); + phase->register_new_node(in_cset_fast_test_cmp, ctrl); + Node* in_cset_fast_test_test = new (phase->C) BoolNode(in_cset_fast_test_cmp, BoolTest::eq); + phase->register_new_node(in_cset_fast_test_test, ctrl); + IfNode* in_cset_fast_test_iff = new (phase->C) IfNode(ctrl, in_cset_fast_test_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); + phase->register_control(in_cset_fast_test_iff, loop, ctrl); + + not_cset_ctrl = new (phase->C) IfTrueNode(in_cset_fast_test_iff); + phase->register_control(not_cset_ctrl, loop, in_cset_fast_test_iff); + + ctrl = new (phase->C) IfFalseNode(in_cset_fast_test_iff); + phase->register_control(ctrl, loop, in_cset_fast_test_iff); +} + +void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase) { + IdealLoopTree*loop = phase->get_loop(ctrl); + const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr()->cast_to_nonconst(); + + // The slow path stub consumes and produces raw memory in addition + // to the existing memory edges + Node* base = find_bottom_mem(ctrl, phase); + MergeMemNode* mm = MergeMemNode::make(phase->C, base); + mm->set_memory_at(Compile::AliasIdxRaw, raw_mem); + phase->register_new_node(mm, ctrl); + + Node* call = new (phase->C) CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_load_reference_barrier", TypeRawPtr::BOTTOM); + call->init_req(TypeFunc::Control, ctrl); + call->init_req(TypeFunc::I_O, phase->C->top()); + call->init_req(TypeFunc::Memory, mm); + call->init_req(TypeFunc::FramePtr, phase->C->top()); + call->init_req(TypeFunc::ReturnAdr, phase->C->top()); + call->init_req(TypeFunc::Parms, val); + phase->register_control(call, loop, ctrl); + ctrl = new (phase->C) ProjNode(call, TypeFunc::Control); + phase->register_control(ctrl, loop, call); + result_mem = new (phase->C) ProjNode(call, TypeFunc::Memory); + phase->register_new_node(result_mem, call); + val = new (phase->C) ProjNode(call, TypeFunc::Parms); + phase->register_new_node(val, call); + val = new (phase->C) CheckCastPPNode(ctrl, val, obj_type); + phase->register_new_node(val, ctrl); +} + +void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) { + Node* ctrl = phase->get_ctrl(barrier); + Node* init_raw_mem = fixer.find_mem(ctrl, barrier); + + // Update the control of all nodes that should be after the + // barrier control flow + uses.clear(); + // Every node that is control dependent on the barrier's input + // control will be after the expanded barrier. The raw memory (if + // its memory is control dependent on the barrier's input control) + // must stay above the barrier. + uses_to_ignore.clear(); + if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) { + uses_to_ignore.push(init_raw_mem); + } + for (uint next = 0; next < uses_to_ignore.size(); next++) { + Node *n = uses_to_ignore.at(next); + for (uint i = 0; i < n->req(); i++) { + Node* in = n->in(i); + if (in != NULL && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) { + uses_to_ignore.push(in); + } + } + } + for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) { + Node* u = ctrl->fast_out(i); + if (u->_idx < last && + u != barrier && + !uses_to_ignore.member(u) && + (u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) && + (ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) { + Node* old_c = phase->ctrl_or_self(u); + Node* c = old_c; + if (c != ctrl || + is_dominator_same_ctrl(old_c, barrier, u, phase) || + ShenandoahBarrierSetC2::is_shenandoah_state_load(u)) { + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(ctrl, region); + if (u->is_CFG()) { + if (phase->idom(u) == ctrl) { + phase->set_idom(u, region, phase->dom_depth(region)); + } + } else if (phase->get_ctrl(u) == ctrl) { + assert(u != init_raw_mem, "should leave input raw mem above the barrier"); + uses.push(u); + } + assert(nb == 1, "more than 1 ctrl input?"); + --i, imax -= nb; + } + } + } +} + +static Node* create_phis_on_call_return(Node* ctrl, Node* c, Node* n, Node* n_clone, const CallProjections& projs, PhaseIdealLoop* phase) { + Node* region = NULL; + while (c != ctrl) { + if (c->is_Region()) { + region = c; + } + c = phase->idom(c); + } + assert(region != NULL, ""); + if (n->is_Bool()) { + Node* bol_clone = n->clone(); + n = n->in(1); + n_clone = n_clone->in(1); + assert(n->is_Cmp() && n_clone->is_Cmp(), "should be cmp"); + Node* cmp_clone = n->clone(); + bol_clone->set_req(1, cmp_clone); + if (n->in(1) != n_clone->in(1)) { + cmp_clone->set_req(1, create_phis_on_call_return(ctrl, region, n->in(1), n_clone->in(1), projs, phase)); + } + if (n->in(2) != n_clone->in(2)) { + cmp_clone->set_req(2, create_phis_on_call_return(ctrl, region, n->in(2), n_clone->in(2), projs, phase)); + } + phase->register_new_node(cmp_clone, region); + phase->register_new_node(bol_clone, region); + return bol_clone; + } + Node* phi = new (phase->C) PhiNode(region, n->bottom_type()); + for (uint j = 1; j < region->req(); j++) { + Node* in = region->in(j); + if (phase->is_dominator(projs.fallthrough_catchproj, in)) { + phi->init_req(j, n); + } else if (phase->is_dominator(projs.catchall_catchproj, in)) { + phi->init_req(j, n_clone); + } else { + phi->init_req(j, create_phis_on_call_return(ctrl, in, n, n_clone, projs, phase)); + } + } + phase->register_new_node(phi, region); + return phi; +} + +void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { + + Unique_Node_List uses; + Node_Stack stack(0); + Node_List clones; + for (int i = phase->C->shenandoah_barriers_count() - 1; i >= 0; i--) { + ShenandoahLoadReferenceBarrierNode* lrb = phase->C->shenandoah_barrier(i); + if (lrb->get_barrier_strength() == ShenandoahLoadReferenceBarrierNode::NONE) { + continue; + } + + Node* ctrl = phase->get_ctrl(lrb); + Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn); + + CallStaticJavaNode* unc = NULL; + Node* unc_ctrl = NULL; + Node* uncasted_val = val; + + for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) { + Node* u = lrb->fast_out(i); + if (u->Opcode() == Op_CastPP && + u->in(0) != NULL && + phase->is_dominator(u->in(0), ctrl)) { + const Type* u_t = phase->igvn().type(u); + + if (u_t->meet(TypePtr::NULL_PTR) != u_t && + u->in(0)->Opcode() == Op_IfTrue && + u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) && + u->in(0)->in(0)->is_If() && + u->in(0)->in(0)->in(1)->Opcode() == Op_Bool && + u->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne && + u->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && + u->in(0)->in(0)->in(1)->in(1)->in(1) == val && + u->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { + IdealLoopTree* loop = phase->get_loop(ctrl); + IdealLoopTree* unc_loop = phase->get_loop(u->in(0)); + + if (!unc_loop->is_member(loop)) { + continue; + } + + Node* branch = no_branches(ctrl, u->in(0), false, phase); + assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch"); + if (branch == NodeSentinel) { + continue; + } + + phase->igvn().replace_input_of(u, 1, val); + phase->igvn().replace_input_of(lrb, ShenandoahLoadReferenceBarrierNode::ValueIn, u); + phase->set_ctrl(u, u->in(0)); + phase->set_ctrl(lrb, u->in(0)); + unc = u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); + unc_ctrl = u->in(0); + val = u; + + for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { + Node* u = val->fast_out(j); + if (u == lrb) continue; + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(val, lrb); + --j; jmax -= nb; + } + + RegionNode* r = new (phase->C) RegionNode(3); + IfNode* iff = unc_ctrl->in(0)->as_If(); + + Node* ctrl_use = unc_ctrl->unique_ctrl_out(); + Node* unc_ctrl_clone = unc_ctrl->clone(); + phase->register_control(unc_ctrl_clone, loop, iff); + Node* c = unc_ctrl_clone; + Node* new_cast = clone_null_check(c, val, unc_ctrl_clone, phase); + r->init_req(1, new_cast->in(0)->in(0)->as_If()->proj_out(0)); + + phase->igvn().replace_input_of(unc_ctrl, 0, c->in(0)); + phase->set_idom(unc_ctrl, c->in(0), phase->dom_depth(unc_ctrl)); + phase->lazy_replace(c, unc_ctrl); + c = NULL;; + phase->igvn().replace_input_of(val, 0, unc_ctrl_clone); + phase->set_ctrl(val, unc_ctrl_clone); + + IfNode* new_iff = new_cast->in(0)->in(0)->as_If(); + fix_null_check(unc, unc_ctrl_clone, r, uses, phase); + Node* iff_proj = iff->proj_out(0); + r->init_req(2, iff_proj); + phase->register_control(r, phase->ltree_root(), iff); + + Node* new_bol = new_iff->in(1)->clone(); + Node* new_cmp = new_bol->in(1)->clone(); + assert(new_cmp->Opcode() == Op_CmpP, "broken"); + assert(new_cmp->in(1) == val->in(1), "broken"); + new_bol->set_req(1, new_cmp); + new_cmp->set_req(1, lrb); + phase->register_new_node(new_bol, new_iff->in(0)); + phase->register_new_node(new_cmp, new_iff->in(0)); + phase->igvn().replace_input_of(new_iff, 1, new_bol); + phase->igvn().replace_input_of(new_cast, 1, lrb); + + for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) { + Node* u = lrb->fast_out(i); + if (u == new_cast || u == new_cmp) { + continue; + } + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(lrb, new_cast); + assert(nb > 0, "no update?"); + --i; imax -= nb; + } + + for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { + Node* u = val->fast_out(i); + if (u == lrb) { + continue; + } + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(val, new_cast); + assert(nb > 0, "no update?"); + --i; imax -= nb; + } + + ctrl = unc_ctrl_clone; + phase->set_ctrl_and_loop(lrb, ctrl); + break; + } + } + } + if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) { + CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava(); + if (call->entry_point() == OptoRuntime::rethrow_stub()) { + // The rethrow call may have too many projections to be + // properly handled here. Given there's no reason for a + // barrier to depend on the call, move it above the call + if (phase->get_ctrl(val) == ctrl) { + assert(val->Opcode() == Op_DecodeN, "unexpected node"); + assert(phase->is_dominator(phase->get_ctrl(val->in(1)), call->in(0)), "Load is too low"); + phase->set_ctrl(val, call->in(0)); + } + phase->set_ctrl(lrb, call->in(0)); + continue; + } + CallProjections projs; + call->extract_projections(&projs, false, false); + + Node* lrb_clone = lrb->clone(); + phase->register_new_node(lrb_clone, projs.catchall_catchproj); + phase->set_ctrl(lrb, projs.fallthrough_catchproj); + + stack.push(lrb, 0); + clones.push(lrb_clone); + + do { + assert(stack.size() == clones.size(), ""); + Node* n = stack.node(); +#ifdef ASSERT + if (n->is_Load()) { + Node* mem = n->in(MemNode::Memory); + for (DUIterator_Fast jmax, j = mem->fast_outs(jmax); j < jmax; j++) { + Node* u = mem->fast_out(j); + assert(!u->is_Store() || !u->is_LoadStore() || phase->get_ctrl(u) != ctrl, "anti dependent store?"); + } + } +#endif + uint idx = stack.index(); + Node* n_clone = clones.at(clones.size()-1); + if (idx < n->outcnt()) { + Node* u = n->raw_out(idx); + Node* c = phase->ctrl_or_self(u); + if (phase->is_dominator(call, c) && phase->is_dominator(c, projs.fallthrough_proj)) { + stack.set_index(idx+1); + assert(!u->is_CFG(), ""); + stack.push(u, 0); + Node* u_clone = u->clone(); + int nb = u_clone->replace_edge(n, n_clone); + assert(nb > 0, "should have replaced some uses"); + phase->register_new_node(u_clone, projs.catchall_catchproj); + clones.push(u_clone); + phase->set_ctrl(u, projs.fallthrough_catchproj); + } else { + bool replaced = false; + if (u->is_Phi()) { + for (uint k = 1; k < u->req(); k++) { + if (u->in(k) == n) { + if (phase->is_dominator(projs.catchall_catchproj, u->in(0)->in(k))) { + phase->igvn().replace_input_of(u, k, n_clone); + replaced = true; + } else if (!phase->is_dominator(projs.fallthrough_catchproj, u->in(0)->in(k))) { + phase->igvn().replace_input_of(u, k, create_phis_on_call_return(ctrl, u->in(0)->in(k), n, n_clone, projs, phase)); + replaced = true; + } + } + } + } else { + if (phase->is_dominator(projs.catchall_catchproj, c)) { + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(n, n_clone); + assert(nb > 0, "should have replaced some uses"); + replaced = true; + } else if (!phase->is_dominator(projs.fallthrough_catchproj, c)) { + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase)); + assert(nb > 0, "should have replaced some uses"); + replaced = true; + } + } + if (!replaced) { + stack.set_index(idx+1); + } + } + } else { + stack.pop(); + clones.pop(); + } + } while (stack.size() > 0); + assert(stack.size() == 0 && clones.size() == 0, ""); + } + } + + // Expand load-reference-barriers + MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase); + Unique_Node_List uses_to_ignore; + for (int i = phase->C->shenandoah_barriers_count() - 1; i >= 0; i--) { + ShenandoahLoadReferenceBarrierNode* lrb = phase->C->shenandoah_barrier(i); + if (lrb->get_barrier_strength() == ShenandoahLoadReferenceBarrierNode::NONE) { + phase->igvn().replace_node(lrb, lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn)); + continue; + } + uint last = phase->C->unique(); + Node* ctrl = phase->get_ctrl(lrb); + Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn); + + + Node* orig_ctrl = ctrl; + + Node* raw_mem = fixer.find_mem(ctrl, lrb); + Node* init_raw_mem = raw_mem; + Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL); + + IdealLoopTree *loop = phase->get_loop(ctrl); + CallStaticJavaNode* unc = lrb->pin_and_expand_null_check(phase->igvn()); + Node* unc_ctrl = NULL; + if (unc != NULL) { + if (val->in(ShenandoahLoadReferenceBarrierNode::Control) != ctrl) { + unc = NULL; + } else { + unc_ctrl = val->in(ShenandoahLoadReferenceBarrierNode::Control); + } + } + + Node* uncasted_val = val; + if (unc != NULL) { + uncasted_val = val->in(1); + } + + Node* heap_stable_ctrl = NULL; + Node* null_ctrl = NULL; + + assert(val->bottom_type()->make_oopptr(), "need oop"); + assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant"); + + enum { _heap_stable = 1, _not_cset, _fwded, _evac_path, _null_path, PATH_LIMIT }; + Node* region = new (phase->C) RegionNode(PATH_LIMIT); + Node* val_phi = new (phase->C) PhiNode(region, uncasted_val->bottom_type()->is_oopptr()); + Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); + + // Stable path. + test_heap_stable(ctrl, raw_mem, heap_stable_ctrl, phase); + IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If(); + + // Heap stable case + region->init_req(_heap_stable, heap_stable_ctrl); + val_phi->init_req(_heap_stable, uncasted_val); + raw_mem_phi->init_req(_heap_stable, raw_mem); + + Node* reg2_ctrl = NULL; + // Null case + test_null(ctrl, val, null_ctrl, phase); + if (null_ctrl != NULL) { + reg2_ctrl = null_ctrl->in(0); + region->init_req(_null_path, null_ctrl); + val_phi->init_req(_null_path, uncasted_val); + raw_mem_phi->init_req(_null_path, raw_mem); + } else { + region->del_req(_null_path); + val_phi->del_req(_null_path); + raw_mem_phi->del_req(_null_path); + } + + // Test for in-cset. + // Wires !in_cset(obj) to slot 2 of region and phis + Node* not_cset_ctrl = NULL; + in_cset_fast_test(ctrl, not_cset_ctrl, uncasted_val, raw_mem, phase); + if (not_cset_ctrl != NULL) { + if (reg2_ctrl == NULL) reg2_ctrl = not_cset_ctrl->in(0); + region->init_req(_not_cset, not_cset_ctrl); + val_phi->init_req(_not_cset, uncasted_val); + raw_mem_phi->init_req(_not_cset, raw_mem); + } + + // Resolve object when orig-value is in cset. + // Make the unconditional resolve for fwdptr. + Node* new_val = uncasted_val; + if (unc_ctrl != NULL) { + // Clone the null check in this branch to allow implicit null check + new_val = clone_null_check(ctrl, val, unc_ctrl, phase); + fix_null_check(unc, unc_ctrl, ctrl->in(0)->as_If()->proj_out(0), uses, phase); + + IfNode* iff = unc_ctrl->in(0)->as_If(); + phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1)); + } + Node* addr = new (phase->C) AddPNode(new_val, uncasted_val, phase->igvn().MakeConX(oopDesc::mark_offset_in_bytes())); + phase->register_new_node(addr, ctrl); + assert(new_val->bottom_type()->isa_oopptr(), "what else?"); + Node* markword = new (phase->C) LoadXNode(ctrl, raw_mem, addr, TypeRawPtr::BOTTOM, TypeX_X, MemNode::unordered); + phase->register_new_node(markword, ctrl); + + // Test if object is forwarded. This is the case if lowest two bits are set. + Node* masked = new (phase->C) AndXNode(markword, phase->igvn().MakeConX(markOopDesc::lock_mask_in_place)); + phase->register_new_node(masked, ctrl); + Node* cmp = new (phase->C) CmpXNode(masked, phase->igvn().MakeConX(markOopDesc::marked_value)); + phase->register_new_node(cmp, ctrl); + + // Only branch to LRB stub if object is not forwarded; otherwise reply with fwd ptr + Node* bol = new (phase->C) BoolNode(cmp, BoolTest::eq); // Equals 3 means it's forwarded + phase->register_new_node(bol, ctrl); + + IfNode* iff = new (phase->C) IfNode(ctrl, bol, PROB_LIKELY(0.999), COUNT_UNKNOWN); + phase->register_control(iff, loop, ctrl); + Node* if_fwd = new (phase->C) IfTrueNode(iff); + phase->register_control(if_fwd, loop, iff); + Node* if_not_fwd = new (phase->C) IfFalseNode(iff); + phase->register_control(if_not_fwd, loop, iff); + + // Decode forward pointer: since we already have the lowest bits, we can just subtract them + // from the mark word without the need for large immediate mask. + Node* masked2 = new (phase->C) SubXNode(markword, masked); + phase->register_new_node(masked2, if_fwd); + Node* fwdraw = new (phase->C) CastX2PNode(masked2); + fwdraw->init_req(0, if_fwd); + phase->register_new_node(fwdraw, if_fwd); + Node* fwd = new (phase->C) CheckCastPPNode(NULL, fwdraw, val->bottom_type()); + phase->register_new_node(fwd, if_fwd); + + // Wire up not-equal-path in slots 3. + region->init_req(_fwded, if_fwd); + val_phi->init_req(_fwded, fwd); + raw_mem_phi->init_req(_fwded, raw_mem); + + // Call lrb-stub and wire up that path in slots 4 + Node* result_mem = NULL; + ctrl = if_not_fwd; + fwd = new_val; + call_lrb_stub(ctrl, fwd, result_mem, raw_mem, phase); + region->init_req(_evac_path, ctrl); + val_phi->init_req(_evac_path, fwd); + raw_mem_phi->init_req(_evac_path, result_mem); + + phase->register_control(region, loop, heap_stable_iff); + Node* out_val = val_phi; + phase->register_new_node(val_phi, region); + phase->register_new_node(raw_mem_phi, region); + + fix_ctrl(lrb, region, fixer, uses, uses_to_ignore, last, phase); + + ctrl = orig_ctrl; + + if (unc != NULL) { + for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { + Node* u = val->fast_out(i); + Node* c = phase->ctrl_or_self(u); + if (u != lrb && (c != ctrl || is_dominator_same_ctrl(c, lrb, u, phase))) { + phase->igvn().rehash_node_delayed(u); + int nb = u->replace_edge(val, out_val); + --i, imax -= nb; + } + } + if (val->outcnt() == 0) { + phase->igvn()._worklist.push(val); + } + } + phase->igvn().replace_node(lrb, out_val); + + follow_barrier_uses(out_val, ctrl, uses, phase); + + for(uint next = 0; next < uses.size(); next++ ) { + Node *n = uses.at(next); + assert(phase->get_ctrl(n) == ctrl, "bad control"); + assert(n != init_raw_mem, "should leave input raw mem above the barrier"); + phase->set_ctrl(n, region); + follow_barrier_uses(n, ctrl, uses, phase); + } + + // The slow path call produces memory: hook the raw memory phi + // from the expanded load reference barrier with the rest of the graph + // which may require adding memory phis at every post dominated + // region and at enclosing loop heads. Use the memory state + // collected in memory_nodes to fix the memory graph. Update that + // memory state as we go. + fixer.fix_mem(ctrl, region, init_raw_mem, raw_mem_for_ctrl, raw_mem_phi, uses); + } + // Done expanding load-reference-barriers. + assert(phase->C->shenandoah_barriers_count() == 0, "all load reference barrier nodes should have been replaced"); + +} + +void ShenandoahBarrierC2Support::move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) { + IdealLoopTree *loop = phase->get_loop(iff); + Node* loop_head = loop->_head; + Node* entry_c = loop_head->in(LoopNode::EntryControl); + + Node* bol = iff->in(1); + Node* cmp = bol->in(1); + Node* andi = cmp->in(1); + Node* load = andi->in(1); + + assert(is_gc_state_load(load), "broken"); + if (!phase->is_dominator(load->in(0), entry_c)) { + Node* mem_ctrl = NULL; + Node* mem = dom_mem(load->in(MemNode::Memory), loop_head, Compile::AliasIdxRaw, mem_ctrl, phase); + load = load->clone(); + load->set_req(MemNode::Memory, mem); + load->set_req(0, entry_c); + phase->register_new_node(load, entry_c); + andi = andi->clone(); + andi->set_req(1, load); + phase->register_new_node(andi, entry_c); + cmp = cmp->clone(); + cmp->set_req(1, andi); + phase->register_new_node(cmp, entry_c); + bol = bol->clone(); + bol->set_req(1, cmp); + phase->register_new_node(bol, entry_c); + + Node* old_bol =iff->in(1); + phase->igvn().replace_input_of(iff, 1, bol); + } +} + +bool ShenandoahBarrierC2Support::identical_backtoback_ifs(Node* n, PhaseIdealLoop* phase) { + if (!n->is_If() || n->is_CountedLoopEnd()) { + return false; + } + Node* region = n->in(0); + + if (!region->is_Region()) { + return false; + } + Node* dom = phase->idom(region); + if (!dom->is_If()) { + return false; + } + + if (!is_heap_stable_test(n) || !is_heap_stable_test(dom)) { + return false; + } + + IfNode* dom_if = dom->as_If(); + Node* proj_true = dom_if->proj_out(1); + Node* proj_false = dom_if->proj_out(0); + + for (uint i = 1; i < region->req(); i++) { + if (phase->is_dominator(proj_true, region->in(i))) { + continue; + } + if (phase->is_dominator(proj_false, region->in(i))) { + continue; + } + return false; + } + + return true; +} + +static bool merge_point_too_heavy(Compile* C, Node* region) { + // Bail out if the region and its phis have too many users. + int weight = 0; + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { + weight += region->fast_out(i)->outcnt(); + } + int nodes_left = C->max_node_limit() - C->live_nodes(); + if (weight * 8 > nodes_left) { +#ifndef PRODUCT + if (PrintOpto) { + tty->print_cr("*** Split-if bails out: %d nodes, region weight %d", C->unique(), weight); + } +#endif + return true; + } else { + return false; + } +} + +static bool merge_point_safe(Node* region) { + // 4799512: Stop split_if_with_blocks from splitting a block with a ConvI2LNode + // having a PhiNode input. This sidesteps the dangerous case where the split + // ConvI2LNode may become TOP if the input Value() does not + // overlap the ConvI2L range, leaving a node which may not dominate its + // uses. + // A better fix for this problem can be found in the BugTraq entry, but + // expediency for Mantis demands this hack. + // 6855164: If the merge point has a FastLockNode with a PhiNode input, we stop + // split_if_with_blocks from splitting a block because we could not move around + // the FastLockNode. + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { + Node* n = region->fast_out(i); + if (n->is_Phi()) { + for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { + Node* m = n->fast_out(j); + if (m->is_FastLock()) + return false; +#ifdef _LP64 + if (m->Opcode() == Op_ConvI2L) + return false; + if (m->is_CastII() && m->isa_CastII()->has_range_check()) { + return false; + } +#endif + } + } + } + return true; +} + +static bool can_split_if(PhaseIdealLoop* phase, Node* n_ctrl) { + if (phase->C->live_nodes() > 35000) { + return false; // Method too big + } + + // Do not do 'split-if' if irreducible loops are present. + if (phase->_has_irreducible_loops) { + return false; + } + + if (merge_point_too_heavy(phase->C, n_ctrl)) { + return false; + } + + // Do not do 'split-if' if some paths are dead. First do dead code + // elimination and then see if its still profitable. + for (uint i = 1; i < n_ctrl->req(); i++) { + if (n_ctrl->in(i) == phase->C->top()) { + return false; + } + } + + // If trying to do a 'Split-If' at the loop head, it is only + // profitable if the cmp folds up on BOTH paths. Otherwise we + // risk peeling a loop forever. + + // CNC - Disabled for now. Requires careful handling of loop + // body selection for the cloned code. Also, make sure we check + // for any input path not being in the same loop as n_ctrl. For + // irreducible loops we cannot check for 'n_ctrl->is_Loop()' + // because the alternative loop entry points won't be converted + // into LoopNodes. + IdealLoopTree *n_loop = phase->get_loop(n_ctrl); + for (uint j = 1; j < n_ctrl->req(); j++) { + if (phase->get_loop(n_ctrl->in(j)) != n_loop) { + return false; + } + } + + // Check for safety of the merge point. + if (!merge_point_safe(n_ctrl)) { + return false; + } + + return true; +} + +void ShenandoahBarrierC2Support::merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase) { + assert(is_heap_stable_test(n), "no other tests"); + if (identical_backtoback_ifs(n, phase)) { + Node* n_ctrl = n->in(0); + if (can_split_if(phase, n_ctrl)) { + IfNode* dom_if = phase->idom(n_ctrl)->as_If(); + if (is_heap_stable_test(n)) { + Node* gc_state_load = n->in(1)->in(1)->in(1)->in(1); + assert(is_gc_state_load(gc_state_load), "broken"); + Node* dom_gc_state_load = dom_if->in(1)->in(1)->in(1)->in(1); + assert(is_gc_state_load(dom_gc_state_load), "broken"); + if (gc_state_load != dom_gc_state_load) { + phase->igvn().replace_node(gc_state_load, dom_gc_state_load); + } + } + PhiNode* bolphi = PhiNode::make_blank(n_ctrl, n->in(1)); + Node* proj_true = dom_if->proj_out(1); + Node* proj_false = dom_if->proj_out(0); + Node* con_true = phase->igvn().makecon(TypeInt::ONE); + Node* con_false = phase->igvn().makecon(TypeInt::ZERO); + + for (uint i = 1; i < n_ctrl->req(); i++) { + if (phase->is_dominator(proj_true, n_ctrl->in(i))) { + bolphi->init_req(i, con_true); + } else { + assert(phase->is_dominator(proj_false, n_ctrl->in(i)), "bad if"); + bolphi->init_req(i, con_false); + } + } + phase->register_new_node(bolphi, n_ctrl); + phase->igvn().replace_input_of(n, 1, bolphi); + phase->do_split_if(n); + } + } +} + +IfNode* ShenandoahBarrierC2Support::find_unswitching_candidate(const IdealLoopTree* loop, PhaseIdealLoop* phase) { + // Find first invariant test that doesn't exit the loop + LoopNode *head = loop->_head->as_Loop(); + IfNode* unswitch_iff = NULL; + Node* n = head->in(LoopNode::LoopBackControl); + int loop_has_sfpts = -1; + while (n != head) { + Node* n_dom = phase->idom(n); + if (n->is_Region()) { + if (n_dom->is_If()) { + IfNode* iff = n_dom->as_If(); + if (iff->in(1)->is_Bool()) { + BoolNode* bol = iff->in(1)->as_Bool(); + if (bol->in(1)->is_Cmp()) { + // If condition is invariant and not a loop exit, + // then found reason to unswitch. + if (is_heap_stable_test(iff) && + (loop_has_sfpts == -1 || loop_has_sfpts == 0)) { + assert(!loop->is_loop_exit(iff), "both branches should be in the loop"); + if (loop_has_sfpts == -1) { + for(uint i = 0; i < loop->_body.size(); i++) { + Node *m = loop->_body[i]; + if (m->is_SafePoint() && !m->is_CallLeaf()) { + loop_has_sfpts = 1; + break; + } + } + if (loop_has_sfpts == -1) { + loop_has_sfpts = 0; + } + } + if (!loop_has_sfpts) { + unswitch_iff = iff; + } + } + } + } + } + } + n = n_dom; + } + return unswitch_iff; +} + + +void ShenandoahBarrierC2Support::optimize_after_expansion(VectorSet &visited, Node_Stack &stack, Node_List &old_new, PhaseIdealLoop* phase) { + Node_List heap_stable_tests; + Node_List gc_state_loads; + stack.push(phase->C->start(), 0); + do { + Node* n = stack.node(); + uint i = stack.index(); + + if (i < n->outcnt()) { + Node* u = n->raw_out(i); + stack.set_index(i+1); + if (!visited.test_set(u->_idx)) { + stack.push(u, 0); + } + } else { + stack.pop(); + if (ShenandoahCommonGCStateLoads && is_gc_state_load(n)) { + gc_state_loads.push(n); + } + if (n->is_If() && is_heap_stable_test(n)) { + heap_stable_tests.push(n); + } + } + } while (stack.size() > 0); + + bool progress; + do { + progress = false; + for (uint i = 0; i < gc_state_loads.size(); i++) { + Node* n = gc_state_loads.at(i); + if (n->outcnt() != 0) { + progress |= try_common_gc_state_load(n, phase); + } + } + } while (progress); + + for (uint i = 0; i < heap_stable_tests.size(); i++) { + Node* n = heap_stable_tests.at(i); + assert(is_heap_stable_test(n), "only evacuation test"); + merge_back_to_back_tests(n, phase); + } + + if (!phase->C->major_progress()) { + VectorSet seen(Thread::current()->resource_area()); + for (uint i = 0; i < heap_stable_tests.size(); i++) { + Node* n = heap_stable_tests.at(i); + IdealLoopTree* loop = phase->get_loop(n); + if (loop != phase->ltree_root() && + loop->_child == NULL && + !loop->_irreducible) { + LoopNode* head = loop->_head->as_Loop(); + if ((!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) && + !seen.test_set(head->_idx)) { + IfNode* iff = find_unswitching_candidate(loop, phase); + if (iff != NULL) { + Node* bol = iff->in(1); + move_heap_stable_test_out_of_loop(iff, phase); + if (loop->policy_unswitching(phase)) { + phase->do_unswitching(loop, old_new); + } else { + // Not proceeding with unswitching. Move load back in + // the loop. + phase->igvn().replace_input_of(iff, 1, bol); + } + } + } + } + } + } +} + +#ifdef ASSERT +void ShenandoahBarrierC2Support::verify_raw_mem(RootNode* root) { + const bool trace = false; + ResourceMark rm; + Unique_Node_List nodes; + Unique_Node_List controls; + Unique_Node_List memories; + + nodes.push(root); + for (uint next = 0; next < nodes.size(); next++) { + Node *n = nodes.at(next); + if (ShenandoahBarrierSetC2::is_shenandoah_lrb_call(n)) { + controls.push(n); + if (trace) { tty->print("XXXXXX verifying"); n->dump(); } + for (uint next2 = 0; next2 < controls.size(); next2++) { + Node *m = controls.at(next2); + for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { + Node* u = m->fast_out(i); + if (u->is_CFG() && !u->is_Root() && + !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1) && + !(u->is_Region() && u->unique_ctrl_out()->Opcode() == Op_Halt)) { + if (trace) { tty->print("XXXXXX pushing control"); u->dump(); } + controls.push(u); + } + } + } + memories.push(n->as_Call()->proj_out(TypeFunc::Memory)); + for (uint next2 = 0; next2 < memories.size(); next2++) { + Node *m = memories.at(next2); + assert(m->bottom_type() == Type::MEMORY, ""); + for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { + Node* u = m->fast_out(i); + if (u->bottom_type() == Type::MEMORY && (u->is_Mem() || u->is_ClearArray())) { + if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } + memories.push(u); + } else if (u->is_LoadStore()) { + if (trace) { tty->print("XXXXXX pushing memory"); u->find_out_with(Op_SCMemProj)->dump(); } + memories.push(u->find_out_with(Op_SCMemProj)); + } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(Compile::AliasIdxRaw) == m) { + if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } + memories.push(u); + } else if (u->is_Phi()) { + assert(u->bottom_type() == Type::MEMORY, ""); + if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) { + assert(controls.member(u->in(0)), ""); + if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } + memories.push(u); + } + } else if (u->is_SafePoint() || u->is_MemBar()) { + for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { + Node* uu = u->fast_out(j); + if (uu->bottom_type() == Type::MEMORY) { + if (trace) { tty->print("XXXXXX pushing memory"); uu->dump(); } + memories.push(uu); + } + } + } + } + } + for (uint next2 = 0; next2 < controls.size(); next2++) { + Node *m = controls.at(next2); + if (m->is_Region()) { + bool all_in = true; + for (uint i = 1; i < m->req(); i++) { + if (!controls.member(m->in(i))) { + all_in = false; + break; + } + } + if (trace) { tty->print("XXX verifying %s", all_in ? "all in" : ""); m->dump(); } + bool found_phi = false; + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax && !found_phi; j++) { + Node* u = m->fast_out(j); + if (u->is_Phi() && memories.member(u)) { + found_phi = true; + for (uint i = 1; i < u->req() && found_phi; i++) { + Node* k = u->in(i); + if (memories.member(k) != controls.member(m->in(i))) { + found_phi = false; + } + } + } + } + assert(found_phi || all_in, ""); + } + } + controls.clear(); + memories.clear(); + } + for( uint i = 0; i < n->len(); ++i ) { + Node *m = n->in(i); + if (m != NULL) { + nodes.push(m); + } + } + } +} +#endif + +#ifdef ASSERT +static bool has_never_branch(Node* root) { + for (uint i = 1; i < root->req(); i++) { + Node* in = root->in(i); + if (in != NULL && in->Opcode() == Op_Halt && in->in(0)->is_Proj() && in->in(0)->in(0)->Opcode() == Op_NeverBranch) { + return true; + } + } + return false; +} +#endif + +void MemoryGraphFixer::collect_memory_nodes() { + Node_Stack stack(0); + VectorSet visited(Thread::current()->resource_area()); + Node_List regions; + + // Walk the raw memory graph and create a mapping from CFG node to + // memory node. Exclude phis for now. + stack.push(_phase->C->root(), 1); + do { + Node* n = stack.node(); + int opc = n->Opcode(); + uint i = stack.index(); + if (i < n->req()) { + Node* mem = NULL; + if (opc == Op_Root) { + Node* in = n->in(i); + int in_opc = in->Opcode(); + if (in_opc == Op_Return || in_opc == Op_Rethrow) { + mem = in->in(TypeFunc::Memory); + } else if (in_opc == Op_Halt) { + if (!in->in(0)->is_Region()) { + Node* proj = in->in(0); + assert(proj->is_Proj(), ""); + Node* in = proj->in(0); + assert(in->is_CallStaticJava() || in->Opcode() == Op_NeverBranch || in->Opcode() == Op_Catch || proj->is_IfProj(), ""); + if (in->is_CallStaticJava()) { + mem = in->in(TypeFunc::Memory); + } else if (in->Opcode() == Op_Catch) { + Node* call = in->in(0)->in(0); + assert(call->is_Call(), ""); + mem = call->in(TypeFunc::Memory); + } else if (in->Opcode() == Op_NeverBranch) { + ResourceMark rm; + Unique_Node_List wq; + wq.push(in); + wq.push(in->as_Multi()->proj_out(0)); + for (uint j = 1; j < wq.size(); j++) { + Node* c = wq.at(j); + assert(!c->is_Root(), "shouldn't leave loop"); + if (c->is_SafePoint()) { + assert(mem == NULL, "only one safepoint"); + mem = c->in(TypeFunc::Memory); + } + for (DUIterator_Fast kmax, k = c->fast_outs(kmax); k < kmax; k++) { + Node* u = c->fast_out(k); + if (u->is_CFG()) { + wq.push(u); + } + } + } + assert(mem != NULL, "should have found safepoint"); + } + } + } else { +#ifdef ASSERT + n->dump(); + in->dump(); +#endif + ShouldNotReachHere(); + } + } else { + assert(n->is_Phi() && n->bottom_type() == Type::MEMORY, ""); + assert(n->adr_type() == TypePtr::BOTTOM || _phase->C->get_alias_index(n->adr_type()) == _alias, ""); + mem = n->in(i); + } + i++; + stack.set_index(i); + if (mem == NULL) { + continue; + } + for (;;) { + if (visited.test_set(mem->_idx) || mem->is_Start()) { + break; + } + if (mem->is_Phi()) { + stack.push(mem, 2); + mem = mem->in(1); + } else if (mem->is_Proj()) { + stack.push(mem, mem->req()); + mem = mem->in(0); + } else if (mem->is_SafePoint() || mem->is_MemBar()) { + mem = mem->in(TypeFunc::Memory); + } else if (mem->is_MergeMem()) { + MergeMemNode* mm = mem->as_MergeMem(); + mem = mm->memory_at(_alias); + } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { + assert(_alias == Compile::AliasIdxRaw, ""); + stack.push(mem, mem->req()); + mem = mem->in(MemNode::Memory); + } else { +#ifdef ASSERT + mem->dump(); +#endif + ShouldNotReachHere(); + } + } + } else { + if (n->is_Phi()) { + // Nothing + } else if (!n->is_Root()) { + Node* c = get_ctrl(n); + _memory_nodes.map(c->_idx, n); + } + stack.pop(); + } + } while(stack.is_nonempty()); + + // Iterate over CFG nodes in rpo and propagate memory state to + // compute memory state at regions, creating new phis if needed. + Node_List rpo_list; + visited.Clear(); + _phase->rpo(_phase->C->root(), stack, visited, rpo_list); + Node* root = rpo_list.pop(); + assert(root == _phase->C->root(), ""); + + const bool trace = false; +#ifdef ASSERT + if (trace) { + for (int i = rpo_list.size() - 1; i >= 0; i--) { + Node* c = rpo_list.at(i); + if (_memory_nodes[c->_idx] != NULL) { + tty->print("X %d", c->_idx); _memory_nodes[c->_idx]->dump(); + } + } + } +#endif + uint last = _phase->C->unique(); + +#ifdef ASSERT + uint8_t max_depth = 0; + for (LoopTreeIterator iter(_phase->ltree_root()); !iter.done(); iter.next()) { + IdealLoopTree* lpt = iter.current(); + max_depth = MAX2(max_depth, lpt->_nest); + } +#endif + + bool progress = true; + int iteration = 0; + Node_List dead_phis; + while (progress) { + progress = false; + iteration++; + assert(iteration <= 2+max_depth || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), ""); + if (trace) { tty->print_cr("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } + IdealLoopTree* last_updated_ilt = NULL; + for (int i = rpo_list.size() - 1; i >= 0; i--) { + Node* c = rpo_list.at(i); + + Node* prev_mem = _memory_nodes[c->_idx]; + if (c->is_Region()) { + Node* prev_region = regions[c->_idx]; + Node* unique = NULL; + for (uint j = 1; j < c->req() && unique != NodeSentinel; j++) { + Node* m = _memory_nodes[c->in(j)->_idx]; + assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "expect memory state"); + if (m != NULL) { + if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) { + assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop(), ""); + // continue + } else if (unique == NULL) { + unique = m; + } else if (m == unique) { + // continue + } else { + unique = NodeSentinel; + } + } + } + assert(unique != NULL, "empty phi???"); + if (unique != NodeSentinel) { + if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c) { + dead_phis.push(prev_region); + } + regions.map(c->_idx, unique); + } else { + Node* phi = NULL; + if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c && prev_region->_idx >= last) { + phi = prev_region; + for (uint k = 1; k < c->req(); k++) { + Node* m = _memory_nodes[c->in(k)->_idx]; + assert(m != NULL, "expect memory state"); + phi->set_req(k, m); + } + } else { + for (DUIterator_Fast jmax, j = c->fast_outs(jmax); j < jmax && phi == NULL; j++) { + Node* u = c->fast_out(j); + if (u->is_Phi() && u->bottom_type() == Type::MEMORY && + (u->adr_type() == TypePtr::BOTTOM || _phase->C->get_alias_index(u->adr_type()) == _alias)) { + phi = u; + for (uint k = 1; k < c->req() && phi != NULL; k++) { + Node* m = _memory_nodes[c->in(k)->_idx]; + assert(m != NULL, "expect memory state"); + if (u->in(k) != m) { + phi = NULL; + } + } + } + } + if (phi == NULL) { + phi = new (_phase->C) PhiNode(c, Type::MEMORY, _phase->C->get_adr_type(_alias)); + for (uint k = 1; k < c->req(); k++) { + Node* m = _memory_nodes[c->in(k)->_idx]; + assert(m != NULL, "expect memory state"); + phi->init_req(k, m); + } + } + } + assert(phi != NULL, ""); + regions.map(c->_idx, phi); + } + Node* current_region = regions[c->_idx]; + if (current_region != prev_region) { + progress = true; + if (prev_region == prev_mem) { + _memory_nodes.map(c->_idx, current_region); + } + } + } else if (prev_mem == NULL || prev_mem->is_Phi() || ctrl_or_self(prev_mem) != c) { + Node* m = _memory_nodes[_phase->idom(c)->_idx]; + assert(m != NULL, "expect memory state"); + if (m != prev_mem) { + _memory_nodes.map(c->_idx, m); + progress = true; + } + } +#ifdef ASSERT + if (trace) { tty->print("X %d", c->_idx); _memory_nodes[c->_idx]->dump(); } +#endif + } + } + + // Replace existing phi with computed memory state for that region + // if different (could be a new phi or a dominating memory node if + // that phi was found to be useless). + while (dead_phis.size() > 0) { + Node* n = dead_phis.pop(); + n->replace_by(_phase->C->top()); + n->destruct(); + } + for (int i = rpo_list.size() - 1; i >= 0; i--) { + Node* c = rpo_list.at(i); + if (c->is_Region()) { + Node* n = regions[c->_idx]; + if (n->is_Phi() && n->_idx >= last && n->in(0) == c) { + _phase->register_new_node(n, c); + } + } + } + for (int i = rpo_list.size() - 1; i >= 0; i--) { + Node* c = rpo_list.at(i); + if (c->is_Region()) { + Node* n = regions[c->_idx]; + for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { + Node* u = c->fast_out(i); + if (u->is_Phi() && u->bottom_type() == Type::MEMORY && + u != n) { + if (u->adr_type() == TypePtr::BOTTOM) { + fix_memory_uses(u, n, n, c); + } else if (_phase->C->get_alias_index(u->adr_type()) == _alias) { + _phase->lazy_replace(u, n); + --i; --imax; + } + } + } + } + } +} + +Node* MemoryGraphFixer::get_ctrl(Node* n) const { + Node* c = _phase->get_ctrl(n); + if (n->is_Proj() && n->in(0) != NULL && n->in(0)->is_Call()) { + assert(c == n->in(0), ""); + CallNode* call = c->as_Call(); + CallProjections projs; + call->extract_projections(&projs, true, false); + if (projs.catchall_memproj != NULL) { + if (projs.fallthrough_memproj == n) { + c = projs.fallthrough_catchproj; + } else { + assert(projs.catchall_memproj == n, ""); + c = projs.catchall_catchproj; + } + } + } + return c; +} + +Node* MemoryGraphFixer::ctrl_or_self(Node* n) const { + if (_phase->has_ctrl(n)) + return get_ctrl(n); + else { + assert (n->is_CFG(), "must be a CFG node"); + return n; + } +} + +bool MemoryGraphFixer::mem_is_valid(Node* m, Node* c) const { + return m != NULL && get_ctrl(m) == c; +} + +Node* MemoryGraphFixer::find_mem(Node* ctrl, Node* n) const { + assert(n == NULL || _phase->ctrl_or_self(n) == ctrl, ""); + Node* mem = _memory_nodes[ctrl->_idx]; + Node* c = ctrl; + while (!mem_is_valid(mem, c) && + (!c->is_CatchProj() || mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(mem))) { + c = _phase->idom(c); + mem = _memory_nodes[c->_idx]; + } + if (n != NULL && mem_is_valid(mem, c)) { + while (!ShenandoahBarrierC2Support::is_dominator_same_ctrl(c, mem, n, _phase) && _phase->ctrl_or_self(mem) == ctrl) { + mem = next_mem(mem, _alias); + } + if (mem->is_MergeMem()) { + mem = mem->as_MergeMem()->memory_at(_alias); + } + if (!mem_is_valid(mem, c)) { + do { + c = _phase->idom(c); + mem = _memory_nodes[c->_idx]; + } while (!mem_is_valid(mem, c) && + (!c->is_CatchProj() || mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(mem))); + } + } + assert(mem->bottom_type() == Type::MEMORY, ""); + return mem; +} + +bool MemoryGraphFixer::has_mem_phi(Node* region) const { + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { + Node* use = region->fast_out(i); + if (use->is_Phi() && use->bottom_type() == Type::MEMORY && + (_phase->C->get_alias_index(use->adr_type()) == _alias)) { + return true; + } + } + return false; +} + +void MemoryGraphFixer::fix_mem(Node* ctrl, Node* new_ctrl, Node* mem, Node* mem_for_ctrl, Node* new_mem, Unique_Node_List& uses) { + assert(_phase->ctrl_or_self(new_mem) == new_ctrl, ""); + const bool trace = false; + DEBUG_ONLY(if (trace) { tty->print("ZZZ control is"); ctrl->dump(); }); + DEBUG_ONLY(if (trace) { tty->print("ZZZ mem is"); mem->dump(); }); + GrowableArray phis; + if (mem_for_ctrl != mem) { + Node* old = mem_for_ctrl; + Node* prev = NULL; + while (old != mem) { + prev = old; + if (old->is_Store() || old->is_ClearArray() || old->is_LoadStore()) { + assert(_alias == Compile::AliasIdxRaw, ""); + old = old->in(MemNode::Memory); + } else if (old->Opcode() == Op_SCMemProj) { + assert(_alias == Compile::AliasIdxRaw, ""); + old = old->in(0); + } else { + ShouldNotReachHere(); + } + } + assert(prev != NULL, ""); + if (new_ctrl != ctrl) { + _memory_nodes.map(ctrl->_idx, mem); + _memory_nodes.map(new_ctrl->_idx, mem_for_ctrl); + } + uint input = (uint)MemNode::Memory; + _phase->igvn().replace_input_of(prev, input, new_mem); + } else { + uses.clear(); + _memory_nodes.map(new_ctrl->_idx, new_mem); + uses.push(new_ctrl); + for(uint next = 0; next < uses.size(); next++ ) { + Node *n = uses.at(next); + assert(n->is_CFG(), ""); + DEBUG_ONLY(if (trace) { tty->print("ZZZ ctrl"); n->dump(); }); + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* u = n->fast_out(i); + if (!u->is_Root() && u->is_CFG() && u != n) { + Node* m = _memory_nodes[u->_idx]; + if (u->is_Region() && + !has_mem_phi(u) && + u->unique_ctrl_out()->Opcode() != Op_Halt) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ region"); u->dump(); }); + DEBUG_ONLY(if (trace && m != NULL) { tty->print("ZZZ mem"); m->dump(); }); + + if (!mem_is_valid(m, u) || !m->is_Phi()) { + bool push = true; + bool create_phi = true; + if (_phase->is_dominator(new_ctrl, u)) { + create_phi = false; + } else if (!_phase->C->has_irreducible_loop()) { + IdealLoopTree* loop = _phase->get_loop(ctrl); + bool do_check = true; + IdealLoopTree* l = loop; + create_phi = false; + while (l != _phase->ltree_root()) { + Node* head = l->_head; + if (head->in(0) == NULL) { + head = _phase->get_ctrl(head); + } + if (_phase->is_dominator(head, u) && _phase->is_dominator(_phase->idom(u), head)) { + create_phi = true; + do_check = false; + break; + } + l = l->_parent; + } + + if (do_check) { + assert(!create_phi, ""); + IdealLoopTree* u_loop = _phase->get_loop(u); + if (u_loop != _phase->ltree_root() && u_loop->is_member(loop)) { + Node* c = ctrl; + while (!_phase->is_dominator(c, u_loop->tail())) { + c = _phase->idom(c); + } + if (!_phase->is_dominator(c, u)) { + do_check = false; + } + } + } + + if (do_check && _phase->is_dominator(_phase->idom(u), new_ctrl)) { + create_phi = true; + } + } + if (create_phi) { + Node* phi = new (_phase->C) PhiNode(u, Type::MEMORY, _phase->C->get_adr_type(_alias)); + _phase->register_new_node(phi, u); + phis.push(phi); + DEBUG_ONLY(if (trace) { tty->print("ZZZ new phi"); phi->dump(); }); + if (!mem_is_valid(m, u)) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting mem"); phi->dump(); }); + _memory_nodes.map(u->_idx, phi); + } else { + DEBUG_ONLY(if (trace) { tty->print("ZZZ NOT setting mem"); m->dump(); }); + for (;;) { + assert(m->is_Mem() || m->is_LoadStore() || m->is_Proj(), ""); + Node* next = NULL; + if (m->is_Proj()) { + next = m->in(0); + } else { + assert(m->is_Mem() || m->is_LoadStore(), ""); + assert(_alias == Compile::AliasIdxRaw, ""); + next = m->in(MemNode::Memory); + } + if (_phase->get_ctrl(next) != u) { + break; + } + if (next->is_MergeMem()) { + assert(_phase->get_ctrl(next->as_MergeMem()->memory_at(_alias)) != u, ""); + break; + } + if (next->is_Phi()) { + assert(next->adr_type() == TypePtr::BOTTOM && next->in(0) == u, ""); + break; + } + m = next; + } + + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting to phi"); m->dump(); }); + assert(m->is_Mem() || m->is_LoadStore(), ""); + uint input = (uint)MemNode::Memory; + _phase->igvn().replace_input_of(m, input, phi); + push = false; + } + } else { + DEBUG_ONLY(if (trace) { tty->print("ZZZ skipping region"); u->dump(); }); + } + if (push) { + uses.push(u); + } + } + } else if (!mem_is_valid(m, u) && + !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1)) { + uses.push(u); + } + } + } + } + for (int i = 0; i < phis.length(); i++) { + Node* n = phis.at(i); + Node* r = n->in(0); + DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi"); n->dump(); }); + for (uint j = 1; j < n->req(); j++) { + Node* m = find_mem(r->in(j), NULL); + _phase->igvn().replace_input_of(n, j, m); + DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi: %d", j); m->dump(); }); + } + } + } + uint last = _phase->C->unique(); + MergeMemNode* mm = NULL; + int alias = _alias; + DEBUG_ONLY(if (trace) { tty->print("ZZZ raw mem is"); mem->dump(); }); + for (DUIterator i = mem->outs(); mem->has_out(i); i++) { + Node* u = mem->out(i); + if (u->_idx < last) { + if (u->is_Mem()) { + if (_phase->C->get_alias_index(u->adr_type()) == alias) { + Node* m = find_mem(_phase->get_ctrl(u), u); + if (m != mem) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); + _phase->igvn().replace_input_of(u, MemNode::Memory, m); + --i; + } + } + } else if (u->is_MergeMem()) { + MergeMemNode* u_mm = u->as_MergeMem(); + if (u_mm->memory_at(alias) == mem) { + MergeMemNode* newmm = NULL; + for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { + Node* uu = u->fast_out(j); + assert(!uu->is_MergeMem(), "chain of MergeMems?"); + if (uu->is_Phi()) { + assert(uu->adr_type() == TypePtr::BOTTOM, ""); + Node* region = uu->in(0); + int nb = 0; + for (uint k = 1; k < uu->req(); k++) { + if (uu->in(k) == u) { + Node* m = find_mem(region->in(k), NULL); + if (m != mem) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", k); uu->dump(); }); + newmm = clone_merge_mem(u, mem, m, _phase->ctrl_or_self(m), i); + if (newmm != u) { + _phase->igvn().replace_input_of(uu, k, newmm); + nb++; + --jmax; + } + } + } + } + if (nb > 0) { + --j; + } + } else { + Node* m = find_mem(_phase->ctrl_or_self(uu), uu); + if (m != mem) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); uu->dump(); }); + newmm = clone_merge_mem(u, mem, m, _phase->ctrl_or_self(m), i); + if (newmm != u) { + _phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); + --j, --jmax; + } + } + } + } + } + } else if (u->is_Phi()) { + assert(u->bottom_type() == Type::MEMORY, "what else?"); + if (_phase->C->get_alias_index(u->adr_type()) == alias || u->adr_type() == TypePtr::BOTTOM) { + Node* region = u->in(0); + bool replaced = false; + for (uint j = 1; j < u->req(); j++) { + if (u->in(j) == mem) { + Node* m = find_mem(region->in(j), NULL); + Node* nnew = m; + if (m != mem) { + if (u->adr_type() == TypePtr::BOTTOM) { + mm = allocate_merge_mem(mem, m, _phase->ctrl_or_self(m)); + nnew = mm; + } + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", j); u->dump(); }); + _phase->igvn().replace_input_of(u, j, nnew); + replaced = true; + } + } + } + if (replaced) { + --i; + } + } + } else if ((u->adr_type() == TypePtr::BOTTOM) || + u->adr_type() == NULL) { + assert(u->adr_type() != NULL || + u->Opcode() == Op_Rethrow || + u->Opcode() == Op_Return || + u->Opcode() == Op_SafePoint || + (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || + (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || + u->Opcode() == Op_CallLeaf, ""); + Node* m = find_mem(_phase->ctrl_or_self(u), u); + if (m != mem) { + mm = allocate_merge_mem(mem, m, _phase->get_ctrl(m)); + _phase->igvn().replace_input_of(u, u->find_edge(mem), mm); + --i; + } + } else if (_phase->C->get_alias_index(u->adr_type()) == alias) { + Node* m = find_mem(_phase->ctrl_or_self(u), u); + if (m != mem) { + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); + _phase->igvn().replace_input_of(u, u->find_edge(mem), m); + --i; + } + } else if (u->adr_type() != TypePtr::BOTTOM && + _memory_nodes[_phase->ctrl_or_self(u)->_idx] == u) { + Node* m = find_mem(_phase->ctrl_or_self(u), u); + assert(m != mem, ""); + // u is on the wrong slice... + assert(u->is_ClearArray(), ""); + DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); + _phase->igvn().replace_input_of(u, u->find_edge(mem), m); + --i; + } + } + } +#ifdef ASSERT + assert(new_mem->outcnt() > 0, ""); + for (int i = 0; i < phis.length(); i++) { + Node* n = phis.at(i); + assert(n->outcnt() > 0, "new phi must have uses now"); + } +#endif +} + +MergeMemNode* MemoryGraphFixer::allocate_merge_mem(Node* mem, Node* rep_proj, Node* rep_ctrl) const { + MergeMemNode* mm = MergeMemNode::make(_phase->C, mem); + mm->set_memory_at(_alias, rep_proj); + _phase->register_new_node(mm, rep_ctrl); + return mm; +} + +MergeMemNode* MemoryGraphFixer::clone_merge_mem(Node* u, Node* mem, Node* rep_proj, Node* rep_ctrl, DUIterator& i) const { + MergeMemNode* newmm = NULL; + MergeMemNode* u_mm = u->as_MergeMem(); + Node* c = _phase->get_ctrl(u); + if (_phase->is_dominator(c, rep_ctrl)) { + c = rep_ctrl; + } else { + assert(_phase->is_dominator(rep_ctrl, c), "one must dominate the other"); + } + if (u->outcnt() == 1) { + if (u->req() > (uint)_alias && u->in(_alias) == mem) { + _phase->igvn().replace_input_of(u, _alias, rep_proj); + --i; + } else { + _phase->igvn().rehash_node_delayed(u); + u_mm->set_memory_at(_alias, rep_proj); + } + newmm = u_mm; + _phase->set_ctrl_and_loop(u, c); + } else { + // can't simply clone u and then change one of its input because + // it adds and then removes an edge which messes with the + // DUIterator + newmm = MergeMemNode::make(_phase->C, u_mm->base_memory()); + for (uint j = 0; j < u->req(); j++) { + if (j < newmm->req()) { + if (j == (uint)_alias) { + newmm->set_req(j, rep_proj); + } else if (newmm->in(j) != u->in(j)) { + newmm->set_req(j, u->in(j)); + } + } else if (j == (uint)_alias) { + newmm->add_req(rep_proj); + } else { + newmm->add_req(u->in(j)); + } + } + if ((uint)_alias >= u->req()) { + newmm->set_memory_at(_alias, rep_proj); + } + _phase->register_new_node(newmm, c); + } + return newmm; +} + +bool MemoryGraphFixer::should_process_phi(Node* phi) const { + if (phi->adr_type() == TypePtr::BOTTOM) { + Node* region = phi->in(0); + for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax; j++) { + Node* uu = region->fast_out(j); + if (uu->is_Phi() && uu != phi && uu->bottom_type() == Type::MEMORY && _phase->C->get_alias_index(uu->adr_type()) == _alias) { + return false; + } + } + return true; + } + return _phase->C->get_alias_index(phi->adr_type()) == _alias; +} + +void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl) const { + uint last = _phase-> C->unique(); + MergeMemNode* mm = NULL; + assert(mem->bottom_type() == Type::MEMORY, ""); + for (DUIterator i = mem->outs(); mem->has_out(i); i++) { + Node* u = mem->out(i); + if (u != replacement && u->_idx < last) { + if (u->is_MergeMem()) { + MergeMemNode* u_mm = u->as_MergeMem(); + if (u_mm->memory_at(_alias) == mem) { + MergeMemNode* newmm = NULL; + for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { + Node* uu = u->fast_out(j); + assert(!uu->is_MergeMem(), "chain of MergeMems?"); + if (uu->is_Phi()) { + if (should_process_phi(uu)) { + Node* region = uu->in(0); + int nb = 0; + for (uint k = 1; k < uu->req(); k++) { + if (uu->in(k) == u && _phase->is_dominator(rep_ctrl, region->in(k))) { + if (newmm == NULL) { + newmm = clone_merge_mem(u, mem, rep_proj, rep_ctrl, i); + } + if (newmm != u) { + _phase->igvn().replace_input_of(uu, k, newmm); + nb++; + --jmax; + } + } + } + if (nb > 0) { + --j; + } + } + } else { + if (rep_ctrl != uu && ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(uu), replacement, uu, _phase)) { + if (newmm == NULL) { + newmm = clone_merge_mem(u, mem, rep_proj, rep_ctrl, i); + } + if (newmm != u) { + _phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); + --j, --jmax; + } + } + } + } + } + } else if (u->is_Phi()) { + assert(u->bottom_type() == Type::MEMORY, "what else?"); + Node* region = u->in(0); + if (should_process_phi(u)) { + bool replaced = false; + for (uint j = 1; j < u->req(); j++) { + if (u->in(j) == mem && _phase->is_dominator(rep_ctrl, region->in(j))) { + Node* nnew = rep_proj; + if (u->adr_type() == TypePtr::BOTTOM) { + if (mm == NULL) { + mm = allocate_merge_mem(mem, rep_proj, rep_ctrl); + } + nnew = mm; + } + _phase->igvn().replace_input_of(u, j, nnew); + replaced = true; + } + } + if (replaced) { + --i; + } + + } + } else if ((u->adr_type() == TypePtr::BOTTOM) || + u->adr_type() == NULL) { + assert(u->adr_type() != NULL || + u->Opcode() == Op_Rethrow || + u->Opcode() == Op_Return || + u->Opcode() == Op_SafePoint || + u->Opcode() == Op_StoreIConditional || + u->Opcode() == Op_StoreLConditional || + (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || + (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || + u->Opcode() == Op_CallLeaf, err_msg("%s", u->Name())); + if (ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(u), replacement, u, _phase)) { + if (mm == NULL) { + mm = allocate_merge_mem(mem, rep_proj, rep_ctrl); + } + _phase->igvn().replace_input_of(u, u->find_edge(mem), mm); + --i; + } + } else if (_phase->C->get_alias_index(u->adr_type()) == _alias) { + if (ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(u), replacement, u, _phase)) { + _phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); + --i; + } + } + } + } +} + +ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj) +: Node(ctrl, obj) { + Compile::current()->add_shenandoah_barrier(this); +} + +const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const { + if (in(ValueIn) == NULL || in(ValueIn)->is_top()) { + return Type::TOP; + } + const Type* t = in(ValueIn)->bottom_type(); + if (t == TypePtr::NULL_PTR) { + return t; + } + return t->is_oopptr(); +} + +const Type* ShenandoahLoadReferenceBarrierNode::Value(PhaseTransform *phase) const { + // Either input is TOP ==> the result is TOP + const Type *t2 = phase->type(in(ValueIn)); + if( t2 == Type::TOP ) return Type::TOP; + + if (t2 == TypePtr::NULL_PTR) { + return t2; + } + + const Type* type = t2->is_oopptr()/*->cast_to_nonconst()*/; + return type; +} + +Node* ShenandoahLoadReferenceBarrierNode::Identity(PhaseTransform *phase) { + Node* value = in(ValueIn); + if (!needs_barrier(phase, value)) { + return value; + } + return this; +} + +bool ShenandoahLoadReferenceBarrierNode::needs_barrier(PhaseTransform* phase, Node* n) { + Unique_Node_List visited; + return needs_barrier_impl(phase, n, visited); +} + +bool ShenandoahLoadReferenceBarrierNode::needs_barrier_impl(PhaseTransform* phase, Node* n, Unique_Node_List &visited) { + if (n == NULL) return false; + if (visited.member(n)) { + return false; // Been there. + } + visited.push(n); + + if (n->is_Allocate()) { + // tty->print_cr("optimize barrier on alloc"); + return false; + } + if (n->is_Call()) { + // tty->print_cr("optimize barrier on call"); + return false; + } + + const Type* type = phase->type(n); + if (type == Type::TOP) { + return false; + } + if (type->make_ptr()->higher_equal(TypePtr::NULL_PTR)) { + // tty->print_cr("optimize barrier on null"); + return false; + } + if (type->make_oopptr() && type->make_oopptr()->const_oop() != NULL) { + // tty->print_cr("optimize barrier on constant"); + return false; + } + + switch (n->Opcode()) { + case Op_AddP: + return true; // TODO: Can refine? + case Op_LoadP: + case Op_GetAndSetN: + case Op_GetAndSetP: + return true; + case Op_Phi: { + for (uint i = 1; i < n->req(); i++) { + if (needs_barrier_impl(phase, n->in(i), visited)) return true; + } + return false; + } + case Op_CheckCastPP: + case Op_CastPP: + return needs_barrier_impl(phase, n->in(1), visited); + case Op_Proj: + return needs_barrier_impl(phase, n->in(0), visited); + case Op_ShenandoahLoadReferenceBarrier: + // tty->print_cr("optimize barrier on barrier"); + return false; + case Op_Parm: + // tty->print_cr("optimize barrier on input arg"); + return false; + case Op_DecodeN: + case Op_EncodeP: + return needs_barrier_impl(phase, n->in(1), visited); + case Op_LoadN: + return true; + case Op_CMoveN: + case Op_CMoveP: + return needs_barrier_impl(phase, n->in(2), visited) || + needs_barrier_impl(phase, n->in(3), visited); + case Op_CreateEx: + return false; + default: + break; + } +#ifdef ASSERT + tty->print("need barrier on?: "); + tty->print_cr("ins:"); + n->dump(2); + tty->print_cr("outs:"); + n->dump(-2); + ShouldNotReachHere(); +#endif + return true; +} + +ShenandoahLoadReferenceBarrierNode::Strength ShenandoahLoadReferenceBarrierNode::get_barrier_strength() { + Unique_Node_List visited; + Node_Stack stack(0); + stack.push(this, 0); + + // Look for strongest strength: go over nodes looking for STRONG ones. + // Stop once we encountered STRONG. Otherwise, walk until we ran out of nodes, + // and then the overall strength is NONE. + Strength strength = NONE; + while (strength != STRONG && stack.size() > 0) { + Node* n = stack.node(); + if (visited.member(n)) { + stack.pop(); + continue; + } + visited.push(n); + bool visit_users = false; + switch (n->Opcode()) { + case Op_CallStaticJava: + case Op_CallDynamicJava: + case Op_CallLeaf: + case Op_CallLeafNoFP: + case Op_CompareAndSwapL: + case Op_CompareAndSwapI: + case Op_CompareAndSwapN: + case Op_CompareAndSwapP: + case Op_ShenandoahCompareAndSwapN: + case Op_ShenandoahCompareAndSwapP: + case Op_GetAndSetL: + case Op_GetAndSetI: + case Op_GetAndSetP: + case Op_GetAndSetN: + case Op_GetAndAddL: + case Op_GetAndAddI: + case Op_FastLock: + case Op_FastUnlock: + case Op_Rethrow: + case Op_Return: + case Op_StoreB: + case Op_StoreC: + case Op_StoreD: + case Op_StoreF: + case Op_StoreL: + case Op_StoreLConditional: + case Op_StoreI: + case Op_StoreIConditional: + case Op_StoreN: + case Op_StoreP: + case Op_StoreVector: + case Op_EncodeP: + case Op_CastP2X: + case Op_SafePoint: + case Op_EncodeISOArray: + case Op_AryEq: + case Op_StrEquals: + case Op_StrComp: + case Op_StrIndexOf: + // Known to require barriers + strength = STRONG; + break; + case Op_CmpP: { + if (n->in(1)->bottom_type()->higher_equal(TypePtr::NULL_PTR) || + n->in(2)->bottom_type()->higher_equal(TypePtr::NULL_PTR)) { + // One of the sides is known null, no need for barrier. + } else { + strength = STRONG; + } + break; + } + case Op_LoadB: + case Op_LoadUB: + case Op_LoadUS: + case Op_LoadD: + case Op_LoadF: + case Op_LoadL: + case Op_LoadI: + case Op_LoadS: + case Op_LoadN: + case Op_LoadP: + case Op_LoadVector: { + const TypePtr* adr_type = n->adr_type(); + int alias_idx = Compile::current()->get_alias_index(adr_type); + Compile::AliasType* alias_type = Compile::current()->alias_type(alias_idx); + ciField* field = alias_type->field(); + bool is_static = field != NULL && field->is_static(); + bool is_final = field != NULL && field->is_final(); + + if (ShenandoahOptimizeStaticFinals && is_static && is_final) { + // Loading the constant does not require barriers: it should be handled + // as part of GC roots already. + } else { + strength = STRONG; + } + break; + } + case Op_Conv2B: + case Op_LoadRange: + case Op_LoadKlass: + case Op_LoadNKlass: + // Do not require barriers + break; + case Op_AddP: + case Op_CheckCastPP: + case Op_CastPP: + case Op_CMoveP: + case Op_Phi: + case Op_ShenandoahLoadReferenceBarrier: + // Whether or not these need the barriers depends on their users + visit_users = true; + break; + default: { +#ifdef ASSERT + fatal(err_msg("Unknown node in get_barrier_strength: %s", NodeClassNames[n->Opcode()])); +#else + // Default to strong: better to have excess barriers, rather than miss some. + strength = STRONG; +#endif + } + } + + stack.pop(); + if (visit_users) { + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* user = n->fast_out(i); + if (user != NULL) { + stack.push(user, 0); + } + } + } + } + return strength; +} + +CallStaticJavaNode* ShenandoahLoadReferenceBarrierNode::pin_and_expand_null_check(PhaseIterGVN& igvn) { + Node* val = in(ValueIn); + + const Type* val_t = igvn.type(val); + + if (val_t->meet(TypePtr::NULL_PTR) != val_t && + val->Opcode() == Op_CastPP && + val->in(0) != NULL && + val->in(0)->Opcode() == Op_IfTrue && + val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) && + val->in(0)->in(0)->is_If() && + val->in(0)->in(0)->in(1)->Opcode() == Op_Bool && + val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne && + val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && + val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) && + val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { + assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), ""); + CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); + return unc; + } + return NULL; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP +#define SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP + +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "memory/allocation.hpp" +#include "opto/addnode.hpp" +#include "opto/graphKit.hpp" +#include "opto/machnode.hpp" +#include "opto/memnode.hpp" +#include "opto/multnode.hpp" +#include "opto/node.hpp" + +class IdealLoopTree; +class PhaseGVN; +class MemoryGraphFixer; + +class ShenandoahBarrierC2Support : public AllStatic { +private: +#ifdef ASSERT + enum verify_type { + ShenandoahLoad, + ShenandoahStore, + ShenandoahValue, + ShenandoahOopStore, + ShenandoahNone + }; + + static bool verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used); + static void report_verify_failure(const char* msg, Node* n1 = NULL, Node* n2 = NULL); +public: + static void verify_raw_mem(RootNode* root); +private: +#endif + static Node* dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase); + static Node* no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase); + static bool is_heap_state_test(Node* iff, int mask); + static bool try_common_gc_state_load(Node *n, PhaseIdealLoop *phase); + static bool has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase); + static Node* find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase); + static void follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase); + static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase); + static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, + PhaseIdealLoop* phase); + static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase); + static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase); + static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses, + PhaseIdealLoop* phase); + static void in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase); + static void move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase); + static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase); + static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase); + static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase); + static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase); + +public: + static bool is_dominator(Node* d_c, Node* n_c, Node* d, Node* n, PhaseIdealLoop* phase); + static bool is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase); + + static bool is_gc_state_load(Node* n); + static bool is_heap_stable_test(Node* iff); + + static bool expand(Compile* C, PhaseIterGVN& igvn); + static void pin_and_expand(PhaseIdealLoop* phase); + static void optimize_after_expansion(VectorSet& visited, Node_Stack& nstack, Node_List& old_new, PhaseIdealLoop* phase); + +#ifdef ASSERT + static void verify(RootNode* root); +#endif +}; + +class MemoryGraphFixer : public ResourceObj { +private: + Node_List _memory_nodes; + int _alias; + PhaseIdealLoop* _phase; + bool _include_lsm; + + void collect_memory_nodes(); + Node* get_ctrl(Node* n) const; + Node* ctrl_or_self(Node* n) const; + bool mem_is_valid(Node* m, Node* c) const; + MergeMemNode* allocate_merge_mem(Node* mem, Node* rep_proj, Node* rep_ctrl) const; + MergeMemNode* clone_merge_mem(Node* u, Node* mem, Node* rep_proj, Node* rep_ctrl, DUIterator& i) const; + void fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl) const; + bool should_process_phi(Node* phi) const; + bool has_mem_phi(Node* region) const; + +public: + MemoryGraphFixer(int alias, bool include_lsm, PhaseIdealLoop* phase) : + _alias(alias), _phase(phase), _include_lsm(include_lsm) { + assert(_alias != Compile::AliasIdxBot, "unsupported"); + collect_memory_nodes(); + } + + Node* find_mem(Node* ctrl, Node* n) const; + void fix_mem(Node* ctrl, Node* region, Node* mem, Node* mem_for_ctrl, Node* mem_phi, Unique_Node_List& uses); + int alias() const { return _alias; } +}; + +class ShenandoahCompareAndSwapPNode : public CompareAndSwapPNode { +public: + ShenandoahCompareAndSwapPNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex) + : CompareAndSwapPNode(c, mem, adr, val, ex) { } + + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { + if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypePtr::NULL_PTR) { + return new (phase->C) CompareAndSwapPNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn)); + } + return NULL; + } + + virtual int Opcode() const; +}; + +class ShenandoahCompareAndSwapNNode : public CompareAndSwapNNode { +public: + ShenandoahCompareAndSwapNNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex) + : CompareAndSwapNNode(c, mem, adr, val, ex) { } + + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { + if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypeNarrowOop::NULL_PTR) { + return new (phase->C) CompareAndSwapNNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn)); + } + return NULL; + } + + virtual int Opcode() const; +}; + +class ShenandoahLoadReferenceBarrierNode : public Node { +public: + enum { + Control, + ValueIn + }; + + enum Strength { + NONE, STRONG + }; + + ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val); + + virtual int Opcode() const; + virtual const Type* bottom_type() const; + virtual const Type* Value(PhaseTransform *phase) const; + virtual const class TypePtr *adr_type() const { return TypeOopPtr::BOTTOM; } + virtual uint match_edge(uint idx) const { + return idx >= ValueIn; + } + virtual uint ideal_reg() const { return Op_RegP; } + + virtual Node* Identity(PhaseTransform *phase); + + uint size_of() const { + return sizeof(*this); + } + + Strength get_barrier_strength(); + CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn); + +private: + bool needs_barrier(PhaseTransform* phase, Node* n); + bool needs_barrier_impl(PhaseTransform* phase, Node* n, Unique_Node_List &visited); +}; + + +#endif // SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTaskqueue.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTaskqueue.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTaskqueue.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTaskqueue.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -149,11 +149,11 @@ public: ObjArrayChunkedTask(oop o = NULL) { - assert(oopDesc::unsafe_equals(decode_oop(encode_oop(o)), o), err_msg("oop can be encoded: " PTR_FORMAT, p2i(o))); + assert(decode_oop(encode_oop(o)) == o, err_msg("oop can be encoded: " PTR_FORMAT, p2i(o))); _obj = encode_oop(o); } ObjArrayChunkedTask(oop o, int chunk, int pow) { - assert(oopDesc::unsafe_equals(decode_oop(encode_oop(o)), o), err_msg("oop can be encoded: " PTR_FORMAT, p2i(o))); + assert(decode_oop(encode_oop(o)) == o, err_msg("oop can be encoded: " PTR_FORMAT, p2i(o))); assert(decode_chunk(encode_chunk(chunk)) == chunk, err_msg("chunk can be encoded: %d", chunk)); assert(decode_pow(encode_pow(pow)) == pow, err_msg("pow can be encoded: %d", pow)); _obj = encode_oop(o) | encode_chunk(chunk) | encode_pow(pow); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTimingTracker.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTimingTracker.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTimingTracker.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTimingTracker.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -64,8 +64,10 @@ ShenandoahTerminationTracker::ShenandoahTerminationTracker(ShenandoahPhaseTimings::Phase phase) : _phase(phase) { assert(_current_termination_phase == ShenandoahPhaseTimings::_num_phases, "Should be invalid"); assert(phase == ShenandoahPhaseTimings::termination || + phase == ShenandoahPhaseTimings::final_traversal_gc_termination || phase == ShenandoahPhaseTimings::full_gc_mark_termination || phase == ShenandoahPhaseTimings::conc_termination || + phase == ShenandoahPhaseTimings::conc_traversal_termination || phase == ShenandoahPhaseTimings::weakrefs_termination || phase == ShenandoahPhaseTimings::full_gc_weakrefs_termination, "Only these phases"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,1202 @@ +/* + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "memory/referenceProcessor.hpp" +#include "utilities/workgroup.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#include "gc_implementation/shenandoah/shenandoahClosures.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahCodeRoots.hpp" +#include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" +#include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp" +#include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" +#include "gc_implementation/shenandoah/shenandoahPhaseTimings.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegionSet.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahOopClosures.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahRootProcessor.hpp" +#include "gc_implementation/shenandoah/shenandoahStringDedup.hpp" +#include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahTimingTracker.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" +#include "gc_implementation/shenandoah/shenandoahUtils.hpp" +#include "gc_implementation/shenandoah/shenandoahVerifier.hpp" +#include "gc_implementation/shenandoah/shenandoahWorkGroup.hpp" + +#include "memory/iterator.hpp" +#include "memory/metaspace.hpp" +#include "memory/resourceArea.hpp" + +/** + * NOTE: We are using the SATB buffer in thread.hpp and satbMarkQueue.hpp, however, it is not an SATB algorithm. + * We're using the buffer as generic oop buffer to enqueue new values in concurrent oop stores, IOW, the algorithm + * is incremental-update-based. + * + * NOTE on interaction with TAMS: we want to avoid traversing new objects for + * several reasons: + * - We will not reclaim them in this cycle anyway, because they are not in the + * cset + * - It makes up for the bulk of work during final-pause + * - It also shortens the concurrent cycle because we don't need to + * pointlessly traverse through newly allocated objects. + * - As a nice side-effect, it solves the I-U termination problem (mutators + * cannot outrun the GC by allocating like crazy) + * - It is an easy way to achieve MWF. What MWF does is to also enqueue the + * target object of stores if it's new. Treating new objects live implicitely + * achieves the same, but without extra barriers. I think the effect of + * shortened final-pause (mentioned above) is the main advantage of MWF. In + * particular, we will not see the head of a completely new long linked list + * in final-pause and end up traversing huge chunks of the heap there. + * - We don't need to see/update the fields of new objects either, because they + * are either still null, or anything that's been stored into them has been + * evacuated+enqueued before (and will thus be treated later). + * + * We achieve this by setting TAMS for each region, and everything allocated + * beyond TAMS will be 'implicitely marked'. + * + * Gotchas: + * - While we want new objects to be implicitely marked, we don't want to count + * them alive. Otherwise the next cycle wouldn't pick them up and consider + * them for cset. This means that we need to protect such regions from + * getting accidentally thrashed at the end of traversal cycle. This is why I + * keep track of alloc-regions and check is_alloc_region() in the trashing + * code. + * - We *need* to traverse through evacuated objects. Those objects are + * pre-existing, and any references in them point to interesting objects that + * we need to see. We also want to count them as live, because we just + * determined that they are alive :-) I achieve this by upping TAMS + * concurrently for every gclab/gc-shared alloc before publishing the + * evacuated object. This way, the GC threads will not consider such objects + * implictely marked, and traverse through them as normal. + */ +class ShenandoahTraversalSATBBufferClosure : public SATBBufferClosure { +private: + ShenandoahObjToScanQueue* _queue; + ShenandoahTraversalGC* _traversal_gc; + ShenandoahHeap* const _heap; + +public: + ShenandoahTraversalSATBBufferClosure(ShenandoahObjToScanQueue* q) : + _queue(q), + _heap(ShenandoahHeap::heap()) + { } + + void do_buffer(void** buffer, size_t size) { + for (size_t i = 0; i < size; ++i) { + oop* p = (oop*) &buffer[i]; + oop obj = oopDesc::load_heap_oop(p); + shenandoah_assert_not_forwarded(p, obj); + if (_heap->marking_context()->mark(obj)) { + _queue->push(ShenandoahMarkTask(obj)); + } + } + } +}; + +class ShenandoahTraversalSATBThreadsClosure : public ThreadClosure { +private: + ShenandoahTraversalSATBBufferClosure* _satb_cl; + int _thread_parity; + +public: + ShenandoahTraversalSATBThreadsClosure(ShenandoahTraversalSATBBufferClosure* satb_cl) : + _satb_cl(satb_cl), + _thread_parity(SharedHeap::heap()->strong_roots_parity()) {} + + void do_thread(Thread* thread) { + if (thread->is_Java_thread()) { + if (thread->claim_oops_do(true, _thread_parity)) { + JavaThread* jt = (JavaThread*)thread; + jt->satb_mark_queue().apply_closure_and_empty(_satb_cl); + } + } else if (thread->is_VM_thread()) { + if (thread->claim_oops_do(true, _thread_parity)) { + JavaThread::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(_satb_cl); + } + } + } +}; + +// Like CLDToOopClosure, but clears has_modified_oops, so that we can record modified CLDs during traversal +// and remark them later during final-traversal. +class ShenandoahMarkCLDClosure : public CLDClosure { +private: + OopClosure* _cl; +public: + ShenandoahMarkCLDClosure(OopClosure* cl) : _cl(cl) {} + void do_cld(ClassLoaderData* cld) { + KlassToOopClosure klasscl(_cl); + cld->oops_do(_cl, &klasscl, true); + } +}; + +// Like CLDToOopClosure, but only process modified CLDs +class ShenandoahRemarkCLDClosure : public CLDClosure { +private: + OopClosure* _cl; +public: + ShenandoahRemarkCLDClosure(OopClosure* cl) : _cl(cl) {} + void do_cld(ClassLoaderData* cld) { + KlassToOopClosure klasscl(_cl); + cld->oops_do(_cl, &klasscl, true); + } +}; + +class ShenandoahInitTraversalCollectionTask : public AbstractGangTask { +private: + ShenandoahRootProcessor* _rp; + ShenandoahHeap* _heap; + ShenandoahCsetCodeRootsIterator _cset_coderoots; +public: + ShenandoahInitTraversalCollectionTask(ShenandoahRootProcessor* rp) : + AbstractGangTask("Shenandoah Init Traversal Collection"), + _rp(rp), + _heap(ShenandoahHeap::heap()), + _cset_coderoots(ShenandoahCodeRoots::cset_iterator()) {} + + void work(uint worker_id) { + ShenandoahParallelWorkerSession worker_session(worker_id); + + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues(); + ShenandoahObjToScanQueue* q = queues->queue(worker_id); + + bool process_refs = _heap->process_references(); + bool unload_classes = _heap->unload_classes(); + ReferenceProcessor* rp = NULL; + if (process_refs) { + rp = _heap->ref_processor(); + } + + // Step 1: Process ordinary GC roots. + { + ShenandoahTraversalRootsClosure roots_cl(q, rp); + ShenandoahMarkCLDClosure cld_cl(&roots_cl); + MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations); + if (unload_classes) { + _rp->process_strong_roots(&roots_cl, &cld_cl, NULL, NULL, NULL, worker_id); + // Need to pre-evac code roots here. Otherwise we might see from-space constants. + ShenandoahWorkerTimings* worker_times = _heap->phase_timings()->worker_times(); + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id); + _cset_coderoots.possibly_parallel_blobs_do(&code_cl); + } else { + _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id); + } + } + } +}; + +class ShenandoahTraversalWeakRootsClosure : public OopClosure { +private: + ShenandoahHeap* const _heap; + + template + void do_oop_work(T* p) { + T o = oopDesc::load_heap_oop(p); + if (!oopDesc::is_null(o)) { + oop obj = oopDesc::decode_heap_oop_not_null(o); + if (_heap->in_collection_set(obj)) { + oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (obj == forw) { + forw = _heap->evacuate_object(obj, Thread::current()); + } + shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc()); + // Update reference. + oopDesc::encode_store_heap_oop_not_null(p, forw); + } + } + } +public: + ShenandoahTraversalWeakRootsClosure() : + _heap(ShenandoahHeap::heap()) {} + + virtual void do_oop(oop* p) { do_oop_work(p); } + virtual void do_oop(narrowOop* p) { do_oop_work(p); } +}; + +class ShenandoahWeakInitTraversalCollectionTask : public AbstractGangTask { +private: + ShenandoahRootProcessor* _rp; + ShenandoahHeap* _heap; +public: + ShenandoahWeakInitTraversalCollectionTask(ShenandoahRootProcessor* rp) : + AbstractGangTask("Shenandoah Weak Init Traversal Collection"), + _rp(rp), + _heap(ShenandoahHeap::heap()) {} + + void work(uint worker_id) { + ShenandoahParallelWorkerSession worker_session(worker_id); + + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahTraversalWeakRootsClosure roots_cl; + CLDToOopClosure cld_cl(&roots_cl); + MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations); + _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id); + } +}; + +class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask { +private: + ShenandoahTaskTerminator* _terminator; + ShenandoahHeap* _heap; +public: + ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) : + AbstractGangTask("Shenandoah Concurrent Traversal Collection"), + _terminator(terminator), + _heap(ShenandoahHeap::heap()) {} + + void work(uint worker_id) { + ShenandoahConcurrentWorkerSession worker_session(worker_id); + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); + + // Drain all outstanding work in queues. + traversal_gc->main_loop(worker_id, _terminator); + } +}; + +class ShenandoahPreFinalTraversalCollectionTask : public AbstractGangTask { +private: + ShenandoahHeap* const _heap; +public: + ShenandoahPreFinalTraversalCollectionTask() : + AbstractGangTask("Shenandoah Pre Final Traversal Collection"), + _heap(ShenandoahHeap::heap()) {} + + void work(uint worker_id) { + ShenandoahParallelWorkerSession worker_session(worker_id); + ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); + ShenandoahObjToScanQueueSet* queues = traversal_gc->task_queues(); + ShenandoahObjToScanQueue* q = queues->queue(worker_id); + + // Step 0: Drain outstanding SATB queues. + ShenandoahTraversalSATBBufferClosure satb_cl(q); + // Process remaining finished SATB buffers. + SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); + while (satb_mq_set.apply_closure_to_completed_buffer(&satb_cl)); + + ShenandoahTraversalSATBThreadsClosure tc(&satb_cl); + Threads::threads_do(&tc); + } +}; + +class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask { +private: + ShenandoahRootProcessor* _rp; + ShenandoahTaskTerminator* _terminator; + ShenandoahHeap* _heap; +public: + ShenandoahFinalTraversalCollectionTask(ShenandoahRootProcessor* rp, ShenandoahTaskTerminator* terminator) : + AbstractGangTask("Shenandoah Final Traversal Collection"), + _rp(rp), + _terminator(terminator), + _heap(ShenandoahHeap::heap()) {} + + void work(uint worker_id) { + ShenandoahParallelWorkerSession worker_session(worker_id); + + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); + + ShenandoahObjToScanQueueSet* queues = traversal_gc->task_queues(); + ShenandoahObjToScanQueue* q = queues->queue(worker_id); + + bool process_refs = _heap->process_references(); + bool unload_classes = _heap->unload_classes(); + ReferenceProcessor* rp = NULL; + if (process_refs) { + rp = _heap->ref_processor(); + } + + // Step 1: Process GC roots. + // For oops in code roots, they are marked, evacuated, enqueued for further traversal, + // and the references to the oops are updated during init pause. New nmethods are handled + // in similar way during nmethod-register process. Therefore, we don't need to rescan code + // roots here. + if (!_heap->is_degenerated_gc_in_progress()) { + ShenandoahTraversalRootsClosure roots_cl(q, rp); + CLDToOopClosure cld_cl(&roots_cl); + if (unload_classes) { + ShenandoahRemarkCLDClosure weak_cld_cl(&roots_cl); + _rp->process_strong_roots(&roots_cl, &cld_cl, &weak_cld_cl, NULL, NULL, worker_id); + } else { + _rp->process_all_roots(&roots_cl, &cld_cl, NULL, NULL, worker_id); + } + } else { + ShenandoahTraversalDegenClosure roots_cl(q, rp); + CLDToOopClosure cld_cl(&roots_cl); + if (unload_classes) { + ShenandoahRemarkCLDClosure weak_cld_cl(&roots_cl); + _rp->process_strong_roots(&roots_cl, &cld_cl, &weak_cld_cl, NULL, NULL, worker_id); + } else { + _rp->process_all_roots(&roots_cl, &cld_cl, NULL, NULL, worker_id); + } + } + + { + ShenandoahWorkerTimings *worker_times = _heap->phase_timings()->worker_times(); + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::FinishQueues, worker_id); + + // Step 3: Finally drain all outstanding work in queues. + traversal_gc->main_loop(worker_id, _terminator); + } + + } +}; + +ShenandoahTraversalGC::ShenandoahTraversalGC(ShenandoahHeap* heap, size_t num_regions) : + _heap(heap), + _task_queues(new ShenandoahObjToScanQueueSet(heap->max_workers())), + _traversal_set(ShenandoahHeapRegionSet()) { + + // Traversal does not support concurrent code root scanning + FLAG_SET_DEFAULT(ShenandoahConcurrentScanCodeRoots, false); + + uint num_queues = heap->max_workers(); + for (uint i = 0; i < num_queues; ++i) { + ShenandoahObjToScanQueue* task_queue = new ShenandoahObjToScanQueue(); + task_queue->initialize(); + _task_queues->register_queue(i, task_queue); + } +} + +ShenandoahTraversalGC::~ShenandoahTraversalGC() { +} + +void ShenandoahTraversalGC::prepare_regions() { + size_t num_regions = _heap->num_regions(); + ShenandoahMarkingContext* const ctx = _heap->marking_context(); + for (size_t i = 0; i < num_regions; i++) { + ShenandoahHeapRegion* region = _heap->get_region(i); + if (_heap->is_bitmap_slice_committed(region)) { + if (_traversal_set.is_in(i)) { + ctx->capture_top_at_mark_start(region); + region->clear_live_data(); + assert(ctx->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared"); + } else { + // Everything outside the traversal set is always considered live. + ctx->reset_top_at_mark_start(region); + } + } else { + // FreeSet may contain uncommitted empty regions, once they are recommitted, + // their TAMS may have old values, so reset them here. + ctx->reset_top_at_mark_start(region); + } + } +} + +void ShenandoahTraversalGC::prepare() { + if (UseTLAB) { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::traversal_gc_accumulate_stats); + _heap->accumulate_statistics_tlabs(); + } + + { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::traversal_gc_make_parsable); + _heap->make_parsable(true); + } + + if (UseTLAB) { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::traversal_gc_resize_tlabs); + _heap->resize_tlabs(); + } + + assert(_heap->marking_context()->is_bitmap_clear(), "need clean mark bitmap"); + assert(!_heap->marking_context()->is_complete(), "should not be complete"); + + // About to choose the collection set, make sure we know which regions are pinned. + { + ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_prepare_sync_pinned); + _heap->sync_pinned_region_status(); + } + + ShenandoahCollectionSet* collection_set = _heap->collection_set(); + { + ShenandoahHeapLocker lock(_heap->lock()); + + collection_set->clear(); + assert(collection_set->count() == 0, "collection set not clear"); + + // Find collection set + _heap->heuristics()->choose_collection_set(collection_set); + prepare_regions(); + + // Rebuild free set + _heap->free_set()->rebuild(); + } + + log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s, " SIZE_FORMAT "%s CSet, " SIZE_FORMAT " CSet regions", + byte_size_in_proper_unit(collection_set->garbage()), proper_unit_for_byte_size(collection_set->garbage()), + byte_size_in_proper_unit(collection_set->live_data()), proper_unit_for_byte_size(collection_set->live_data()), + collection_set->count()); +} + +void ShenandoahTraversalGC::init_traversal_collection() { + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC"); + + if (ShenandoahVerify) { + _heap->verifier()->verify_before_traversal(); + } + + if (VerifyBeforeGC) { + Universe::verify(); + } + + { + ShenandoahGCPhase phase_prepare(ShenandoahPhaseTimings::traversal_gc_prepare); + prepare(); + } + + _heap->set_concurrent_traversal_in_progress(true); + + bool process_refs = _heap->process_references(); + if (process_refs) { + ReferenceProcessor* rp = _heap->ref_processor(); + rp->enable_discovery(true /*verify_no_refs*/, true); + rp->setup_policy(_heap->collector_policy()->should_clear_all_soft_refs()); + } + + { + ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work); + assert(_task_queues->is_empty(), "queues must be empty before traversal GC"); + TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats()); + + + { + COMPILER2_PRESENT(DerivedPointerTable::clear()); + uint nworkers = _heap->workers()->active_workers(); + task_queues()->reserve(nworkers); + ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::init_traversal_gc_work); + ShenandoahInitTraversalCollectionTask traversal_task(&rp); + _heap->workers()->run_task(&traversal_task); + COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); + } + + + if (_heap->unload_classes()) { + COMPILER2_PRESENT(DerivedPointerTable::clear()); + uint nworkers = _heap->workers()->active_workers(); + task_queues()->reserve(nworkers); + ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::init_weak_traversal_gc_work); + ShenandoahWeakInitTraversalCollectionTask task(&rp); + _heap->workers()->run_task(&task); + COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); + } + } + + if (ShenandoahPacing) { + _heap->pacer()->setup_for_traversal(); + } +} + +void ShenandoahTraversalGC::main_loop(uint w, ShenandoahTaskTerminator* t) { + ShenandoahObjToScanQueue* q = task_queues()->queue(w); + + // Initialize live data. + jushort* ld = _heap->get_liveness_cache(w); + + ReferenceProcessor* rp = NULL; + if (_heap->process_references()) { + rp = _heap->ref_processor(); + } + { + if (!_heap->is_degenerated_gc_in_progress()) { + if (_heap->unload_classes()) { + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w); + ShenandoahTraversalMetadataDedupClosure cl(q, rp, dq); + main_loop_work(&cl, ld, w, t); + } else { + ShenandoahTraversalMetadataClosure cl(q, rp); + main_loop_work(&cl, ld, w, t); + } + } else { + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w); + ShenandoahTraversalDedupClosure cl(q, rp, dq); + main_loop_work(&cl, ld, w, t); + } else { + ShenandoahTraversalClosure cl(q, rp); + main_loop_work(&cl, ld, w, t); + } + } + } else { + if (_heap->unload_classes()) { + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w); + ShenandoahTraversalMetadataDedupDegenClosure cl(q, rp, dq); + main_loop_work(&cl, ld, w, t); + } else { + ShenandoahTraversalMetadataDegenClosure cl(q, rp); + main_loop_work(&cl, ld, w, t); + } + } else { + if (ShenandoahStringDedup::is_enabled()) { + ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w); + ShenandoahTraversalDedupDegenClosure cl(q, rp, dq); + main_loop_work(&cl, ld, w, t); + } else { + ShenandoahTraversalDegenClosure cl(q, rp); + main_loop_work(&cl, ld, w, t); + } + } + } + } + + _heap->flush_liveness_cache(w); +} + +template +void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worker_id, ShenandoahTaskTerminator* terminator) { + ShenandoahObjToScanQueueSet* queues = task_queues(); + ShenandoahObjToScanQueue* q = queues->queue(worker_id); + ShenandoahConcurrentMark* conc_mark = _heap->concurrent_mark(); + + uintx stride = ShenandoahMarkLoopStride; + + ShenandoahMarkTask task; + + // Process outstanding queues, if any. + q = queues->claim_next(); + while (q != NULL) { + if (_heap->cancelled_gc()) { + return; + } + + for (uint i = 0; i < stride; i++) { + if (q->pop(task)) { + conc_mark->do_task(q, cl, live_data, &task); + } else { + assert(q->is_empty(), "Must be empty"); + q = queues->claim_next(); + break; + } + } + } + + if (_heap->cancelled_gc()) return; + + // Normal loop. + q = queues->queue(worker_id); + + ShenandoahTraversalSATBBufferClosure drain_satb(q); + SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); + + int seed = 17; + + while (true) { + if (_heap->cancelled_gc()) return; + + while (satb_mq_set.completed_buffers_num() > 0) { + satb_mq_set.apply_closure_to_completed_buffer(&drain_satb); + } + + uint work = 0; + for (uint i = 0; i < stride; i++) { + if (q->pop(task) || + queues->steal(worker_id, &seed, task)) { + conc_mark->do_task(q, cl, live_data, &task); + work++; + } else { + break; + } + } + + if (work == 0) { + // No more work, try to terminate + ShenandoahEvacOOMScopeLeaver oom_scope_leaver; + ShenandoahTerminationTimingsTracker term_tracker(worker_id); + ShenandoahTerminatorTerminator tt(_heap); + + if (terminator->offer_termination(&tt)) return; + } + } +} + +void ShenandoahTraversalGC::concurrent_traversal_collection() { + ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal); + if (!_heap->cancelled_gc()) { + uint nworkers = _heap->workers()->active_workers(); + task_queues()->reserve(nworkers); + ShenandoahTerminationTracker tracker(ShenandoahPhaseTimings::conc_traversal_termination); + + ShenandoahTaskTerminator terminator(nworkers, task_queues()); + ShenandoahConcurrentTraversalCollectionTask task(&terminator); + _heap->workers()->run_task(&task); + } + + if (!_heap->cancelled_gc() && ShenandoahPreclean && _heap->process_references()) { + preclean_weak_refs(); + } +} + +void ShenandoahTraversalGC::final_traversal_collection() { + _heap->make_parsable(true); + + if (!_heap->cancelled_gc()) { + COMPILER2_PRESENT(DerivedPointerTable::clear()); + ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work); + uint nworkers = _heap->workers()->active_workers(); + task_queues()->reserve(nworkers); + + // Finish traversal + { + SharedHeap::StrongRootsScope scope(_heap, true); + ShenandoahPreFinalTraversalCollectionTask task; + _heap->workers()->run_task(&task); + } + + ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::final_traversal_gc_work); + ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination); + ShenandoahTaskTerminator terminator(nworkers, task_queues()); + ShenandoahFinalTraversalCollectionTask task(&rp, &terminator); + _heap->workers()->run_task(&task); + COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); + } + + if (!_heap->cancelled_gc()) { + if (_heap->process_references()) { + weak_refs_work(); + } else { + ShenandoahConcurrentMark::cleanup_jni_refs(); + } + } + + if (!_heap->cancelled_gc()) { + fixup_roots(); + if (_heap->unload_classes()) { + _heap->unload_classes_and_cleanup_tables(false); + } else { + ShenandoahIsAliveSelector alive; + StringTable::unlink(alive.is_alive_closure()); + } + } + + if (!_heap->cancelled_gc()) { + assert(_task_queues->is_empty(), "queues must be empty after traversal GC"); + TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats()); + TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats()); + + // No more marking expected + _heap->mark_complete_marking_context(); + + // Resize metaspace + MetaspaceGC::compute_new_size(); + + // Need to see that pinned region status is updated: newly pinned regions must not + // be trashed. New unpinned regions should be trashed. + { + ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_sync_pinned); + _heap->sync_pinned_region_status(); + } + + // Still good? We can now trash the cset, and make final verification + { + ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_cleanup); + ShenandoahHeapLocker lock(_heap->lock()); + + // Trash everything + // Clear immediate garbage regions. + size_t num_regions = _heap->num_regions(); + + ShenandoahHeapRegionSet* traversal_regions = traversal_set(); + ShenandoahFreeSet* free_regions = _heap->free_set(); + ShenandoahMarkingContext* const ctx = _heap->marking_context(); + free_regions->clear(); + for (size_t i = 0; i < num_regions; i++) { + ShenandoahHeapRegion* r = _heap->get_region(i); + bool not_allocated = ctx->top_at_mark_start(r) == r->top(); + + bool candidate = traversal_regions->is_in(r) && !r->has_live() && not_allocated; + if (r->is_humongous_start() && candidate) { + // Trash humongous. + HeapWord* humongous_obj = r->bottom(); + assert(!ctx->is_marked(oop(humongous_obj)), "must not be marked"); + r->make_trash_immediate(); + while (i + 1 < num_regions && _heap->get_region(i + 1)->is_humongous_continuation()) { + i++; + r = _heap->get_region(i); + assert(r->is_humongous_continuation(), "must be humongous continuation"); + r->make_trash_immediate(); + } + } else if (!r->is_empty() && candidate) { + // Trash regular. + assert(!r->is_humongous(), "handled above"); + assert(!r->is_trash(), "must not already be trashed"); + r->make_trash_immediate(); + } + } + _heap->collection_set()->clear(); + _heap->free_set()->rebuild(); + reset(); + } + + assert(_task_queues->is_empty(), "queues must be empty after traversal GC"); + _heap->set_concurrent_traversal_in_progress(false); + assert(!_heap->cancelled_gc(), "must not be cancelled when getting out here"); + + if (ShenandoahVerify) { + _heap->verifier()->verify_after_traversal(); + } + + if (VerifyAfterGC) { + Universe::verify(); + } + } +} + +class ShenandoahTraversalFixRootsClosure : public OopClosure { +private: + template + inline void do_oop_work(T* p) { + T o = oopDesc::load_heap_oop(p); + if (!oopDesc::is_null(o)) { + oop obj = oopDesc::decode_heap_oop_not_null(o); + oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (obj != forw) { + oopDesc::encode_store_heap_oop_not_null(p, forw); + } + } + } + +public: + inline void do_oop(oop* p) { do_oop_work(p); } + inline void do_oop(narrowOop* p) { do_oop_work(p); } +}; + +class ShenandoahTraversalFixRootsTask : public AbstractGangTask { +private: + ShenandoahRootProcessor* _rp; + +public: + ShenandoahTraversalFixRootsTask(ShenandoahRootProcessor* rp) : + AbstractGangTask("Shenandoah traversal fix roots"), + _rp(rp) { + assert(ShenandoahHeap::heap()->has_forwarded_objects(), "Must be"); + } + + void work(uint worker_id) { + ShenandoahParallelWorkerSession worker_session(worker_id); + ShenandoahTraversalFixRootsClosure cl; + MarkingCodeBlobClosure blobsCl(&cl, CodeBlobToOopClosure::FixRelocations); + CLDToOopClosure cldCl(&cl); + _rp->process_all_roots(&cl, &cldCl, &blobsCl, NULL, worker_id); + } +}; + +void ShenandoahTraversalGC::fixup_roots() { + COMPILER2_PRESENT(DerivedPointerTable::clear()); + ShenandoahRootProcessor rp(_heap, _heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots); + ShenandoahTraversalFixRootsTask update_roots_task(&rp); + _heap->workers()->run_task(&update_roots_task); + COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +} + +void ShenandoahTraversalGC::reset() { + _task_queues->clear(); +} + +ShenandoahObjToScanQueueSet* ShenandoahTraversalGC::task_queues() { + return _task_queues; +} + +class ShenandoahTraversalCancelledGCYieldClosure : public YieldClosure { +private: + ShenandoahHeap* const _heap; +public: + ShenandoahTraversalCancelledGCYieldClosure() : _heap(ShenandoahHeap::heap()) {}; + virtual bool should_return() { return _heap->cancelled_gc(); } +}; + +class ShenandoahTraversalPrecleanCompleteGCClosure : public VoidClosure { +public: + void do_void() { + ShenandoahHeap* sh = ShenandoahHeap::heap(); + ShenandoahTraversalGC* traversal_gc = sh->traversal_gc(); + assert(sh->process_references(), "why else would we be here?"); + ShenandoahTaskTerminator terminator(1, traversal_gc->task_queues()); + shenandoah_assert_rp_isalive_installed(); + traversal_gc->main_loop((uint) 0, &terminator); + } +}; + +class ShenandoahTraversalKeepAliveUpdateClosure : public OopClosure { +private: + ShenandoahObjToScanQueue* _queue; + Thread* _thread; + ShenandoahTraversalGC* _traversal_gc; + ShenandoahMarkingContext* const _mark_context; + + template + inline void do_oop_work(T* p) { + _traversal_gc->process_oop(p, _thread, _queue, _mark_context); + } + +public: + ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : + _queue(q), _thread(Thread::current()), + _traversal_gc(ShenandoahHeap::heap()->traversal_gc()), + _mark_context(ShenandoahHeap::heap()->marking_context()) {} + + void do_oop(narrowOop* p) { do_oop_work(p); } + void do_oop(oop* p) { do_oop_work(p); } +}; + +class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure { +private: + ShenandoahObjToScanQueue* _queue; + Thread* _thread; + ShenandoahTraversalGC* _traversal_gc; + ShenandoahMarkingContext* const _mark_context; + + template + inline void do_oop_work(T* p) { + _traversal_gc->process_oop(p, _thread, _queue, _mark_context); + } + +public: + ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : + _queue(q), _thread(Thread::current()), + _traversal_gc(ShenandoahHeap::heap()->traversal_gc()), + _mark_context(ShenandoahHeap::heap()->marking_context()) {} + + void do_oop(narrowOop* p) { do_oop_work(p); } + void do_oop(oop* p) { do_oop_work(p); } +}; + +class ShenandoahTraversalSingleThreadKeepAliveUpdateClosure : public OopClosure { +private: + ShenandoahObjToScanQueue* _queue; + Thread* _thread; + ShenandoahTraversalGC* _traversal_gc; + ShenandoahMarkingContext* const _mark_context; + + template + inline void do_oop_work(T* p) { + ShenandoahEvacOOMScope evac_scope; + _traversal_gc->process_oop(p, _thread, _queue, _mark_context); + } + +public: + ShenandoahTraversalSingleThreadKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : + _queue(q), _thread(Thread::current()), + _traversal_gc(ShenandoahHeap::heap()->traversal_gc()), + _mark_context(ShenandoahHeap::heap()->marking_context()) {} + + void do_oop(narrowOop* p) { do_oop_work(p); } + void do_oop(oop* p) { do_oop_work(p); } +}; + +class ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure : public OopClosure { +private: + ShenandoahObjToScanQueue* _queue; + Thread* _thread; + ShenandoahTraversalGC* _traversal_gc; + ShenandoahMarkingContext* const _mark_context; + + template + inline void do_oop_work(T* p) { + ShenandoahEvacOOMScope evac_scope; + _traversal_gc->process_oop(p, _thread, _queue, _mark_context); + } + +public: + ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : + _queue(q), _thread(Thread::current()), + _traversal_gc(ShenandoahHeap::heap()->traversal_gc()), + _mark_context(ShenandoahHeap::heap()->marking_context()) {} + + void do_oop(narrowOop* p) { do_oop_work(p); } + void do_oop(oop* p) { do_oop_work(p); } +}; + +class ShenandoahTraversalPrecleanTask : public AbstractGangTask { +private: + ReferenceProcessor* _rp; + +public: + ShenandoahTraversalPrecleanTask(ReferenceProcessor* rp) : + AbstractGangTask("Precleaning task"), + _rp(rp) {} + + void work(uint worker_id) { + assert(worker_id == 0, "The code below is single-threaded, only one worker is expected"); + ShenandoahParallelWorkerSession worker_session(worker_id); + ShenandoahEvacOOMScope oom_evac_scope; + + ShenandoahHeap* sh = ShenandoahHeap::heap(); + + ShenandoahObjToScanQueue* q = sh->traversal_gc()->task_queues()->queue(worker_id); + + ShenandoahForwardedIsAliveClosure is_alive; + ShenandoahTraversalCancelledGCYieldClosure yield; + ShenandoahTraversalPrecleanCompleteGCClosure complete_gc; + ShenandoahTraversalKeepAliveUpdateClosure keep_alive(q); + ResourceMark rm; + _rp->preclean_discovered_references(&is_alive, &keep_alive, + &complete_gc, &yield, + NULL, sh->shenandoah_policy()->tracer()->gc_id()); + } +}; + +void ShenandoahTraversalGC::preclean_weak_refs() { + // Pre-cleaning weak references before diving into STW makes sense at the + // end of concurrent mark. This will filter out the references which referents + // are alive. Note that ReferenceProcessor already filters out these on reference + // discovery, and the bulk of work is done here. This phase processes leftovers + // that missed the initial filtering, i.e. when referent was marked alive after + // reference was discovered by RP. + + assert(_heap->process_references(), "sanity"); + assert(!_heap->is_degenerated_gc_in_progress(), "must be in concurrent non-degenerated phase"); + + // Shortcut if no references were discovered to avoid winding up threads. + ReferenceProcessor* rp = _heap->ref_processor(); + ReferenceProcessorMTDiscoveryMutator fix_mt_discovery(rp, false); + + shenandoah_assert_rp_isalive_not_installed(); + ShenandoahForwardedIsAliveClosure is_alive; + ReferenceProcessorIsAliveMutator fix_isalive(rp, &is_alive); + + assert(task_queues()->is_empty(), "Should be empty"); + + // Execute precleaning in the worker thread: it will give us GCLABs, String dedup + // queues and other goodies. When upstream ReferenceProcessor starts supporting + // parallel precleans, we can extend this to more threads. + ShenandoahPushWorkerScope scope(_heap->workers(), 1, /* check_workers = */ false); + + WorkGang* workers = _heap->workers(); + uint nworkers = workers->active_workers(); + assert(nworkers == 1, "This code uses only a single worker"); + task_queues()->reserve(nworkers); + + ShenandoahTraversalPrecleanTask task(rp); + workers->run_task(&task); + + assert(_heap->cancelled_gc() || task_queues()->is_empty(), "Should be empty"); +} + +// Weak Reference Closures +class ShenandoahTraversalDrainMarkingStackClosure: public VoidClosure { + uint _worker_id; + ShenandoahTaskTerminator* _terminator; + bool _reset_terminator; + +public: + ShenandoahTraversalDrainMarkingStackClosure(uint worker_id, ShenandoahTaskTerminator* t, bool reset_terminator = false): + _worker_id(worker_id), + _terminator(t), + _reset_terminator(reset_terminator) { + } + + void do_void() { + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); + + ShenandoahHeap* sh = ShenandoahHeap::heap(); + ShenandoahTraversalGC* traversal_gc = sh->traversal_gc(); + assert(sh->process_references(), "why else would we be here?"); + shenandoah_assert_rp_isalive_installed(); + + traversal_gc->main_loop(_worker_id, _terminator); + + if (_reset_terminator) { + _terminator->reset_for_reuse(); + } + } +}; + +class ShenandoahTraversalSingleThreadedDrainMarkingStackClosure: public VoidClosure { + uint _worker_id; + ShenandoahTaskTerminator* _terminator; + bool _reset_terminator; + +public: + ShenandoahTraversalSingleThreadedDrainMarkingStackClosure(uint worker_id, ShenandoahTaskTerminator* t, bool reset_terminator = false): + _worker_id(worker_id), + _terminator(t), + _reset_terminator(reset_terminator) { + } + + void do_void() { + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); + + ShenandoahHeap* sh = ShenandoahHeap::heap(); + ShenandoahTraversalGC* traversal_gc = sh->traversal_gc(); + assert(sh->process_references(), "why else would we be here?"); + shenandoah_assert_rp_isalive_installed(); + + ShenandoahEvacOOMScope evac_scope; + traversal_gc->main_loop(_worker_id, _terminator); + + if (_reset_terminator) { + _terminator->reset_for_reuse(); + } + } +}; + +void ShenandoahTraversalGC::weak_refs_work() { + assert(_heap->process_references(), "sanity"); + + ShenandoahPhaseTimings::Phase phase_root = ShenandoahPhaseTimings::weakrefs; + + ShenandoahGCPhase phase(phase_root); + + ReferenceProcessor* rp = _heap->ref_processor(); + + // NOTE: We cannot shortcut on has_discovered_references() here, because + // we will miss marking JNI Weak refs then, see implementation in + // ReferenceProcessor::process_discovered_references. + weak_refs_work_doit(); + + rp->verify_no_references_recorded(); + assert(!rp->discovery_enabled(), "Post condition"); + +} + +class ShenandoahTraversalRefProcTaskProxy : public AbstractGangTask { +private: + AbstractRefProcTaskExecutor::ProcessTask& _proc_task; + ShenandoahTaskTerminator* _terminator; + +public: + ShenandoahTraversalRefProcTaskProxy(AbstractRefProcTaskExecutor::ProcessTask& proc_task, + ShenandoahTaskTerminator* t) : + AbstractGangTask("Process reference objects in parallel"), + _proc_task(proc_task), + _terminator(t) { + } + + void work(uint worker_id) { + ShenandoahEvacOOMScope oom_evac_scope; + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); + ShenandoahHeap* heap = ShenandoahHeap::heap(); + ShenandoahTraversalDrainMarkingStackClosure complete_gc(worker_id, _terminator); + + ShenandoahForwardedIsAliveClosure is_alive; + if (!heap->is_degenerated_gc_in_progress()) { + ShenandoahTraversalKeepAliveUpdateClosure keep_alive(heap->traversal_gc()->task_queues()->queue(worker_id)); + _proc_task.work(worker_id, is_alive, keep_alive, complete_gc); + } else { + ShenandoahTraversalKeepAliveUpdateDegenClosure keep_alive(heap->traversal_gc()->task_queues()->queue(worker_id)); + _proc_task.work(worker_id, is_alive, keep_alive, complete_gc); + } + } +}; + +class ShenandoahTraversalRefEnqueueTaskProxy : public AbstractGangTask { +private: + AbstractRefProcTaskExecutor::EnqueueTask& _enqueue_task; + +public: + ShenandoahTraversalRefEnqueueTaskProxy(AbstractRefProcTaskExecutor::EnqueueTask& enqueue_task) : + AbstractGangTask("Enqueue reference objects in parallel"), + _enqueue_task(enqueue_task) { + } + + void work(uint worker_id) { + _enqueue_task.work(worker_id); + } +}; + +class ShenandoahTraversalRefProcTaskExecutor : public AbstractRefProcTaskExecutor { +private: + WorkGang* _workers; + +public: + ShenandoahTraversalRefProcTaskExecutor(WorkGang* workers) : _workers(workers) {} + + // Executes a task using worker threads. + void execute(ProcessTask& task) { + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); + + // Shortcut execution if task is empty. + // This should be replaced with the generic ReferenceProcessor shortcut, + // see JDK-8181214, JDK-8043575, JDK-6938732. + if (task.is_empty()) { + return; + } + + ShenandoahHeap* heap = ShenandoahHeap::heap(); + ShenandoahTraversalGC* traversal_gc = heap->traversal_gc(); + uint nworkers = _workers->active_workers(); + traversal_gc->task_queues()->reserve(nworkers); + + ShenandoahTaskTerminator terminator(nworkers, traversal_gc->task_queues()); + ShenandoahTraversalRefProcTaskProxy proc_task_proxy(task, &terminator); + _workers->run_task(&proc_task_proxy); + } + + void execute(EnqueueTask& task) { + ShenandoahTraversalRefEnqueueTaskProxy enqueue_task_proxy(task); + _workers->run_task(&enqueue_task_proxy); + } +}; + +void ShenandoahTraversalGC::weak_refs_work_doit() { + ReferenceProcessor* rp = _heap->ref_processor(); + + ShenandoahPhaseTimings::Phase phase_process = ShenandoahPhaseTimings::weakrefs_process; + ShenandoahPhaseTimings::Phase phase_enqueue = ShenandoahPhaseTimings::weakrefs_enqueue; + + shenandoah_assert_rp_isalive_not_installed(); + ShenandoahForwardedIsAliveClosure is_alive; + ReferenceProcessorIsAliveMutator fix_isalive(rp, &is_alive); + + WorkGang* workers = _heap->workers(); + uint nworkers = workers->active_workers(); + + rp->setup_policy(_heap->collector_policy()->should_clear_all_soft_refs()); + rp->set_active_mt_degree(nworkers); + + assert(task_queues()->is_empty(), "Should be empty"); + + // complete_gc and keep_alive closures instantiated here are only needed for + // single-threaded path in RP. They share the queue 0 for tracking work, which + // simplifies implementation. Since RP may decide to call complete_gc several + // times, we need to be able to reuse the terminator. + uint serial_worker_id = 0; + ShenandoahTaskTerminator terminator(1, task_queues()); + ShenandoahTraversalSingleThreadedDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true); + ShenandoahTraversalRefProcTaskExecutor executor(workers); + + if (!_heap->is_degenerated_gc_in_progress()) { + ShenandoahTraversalSingleThreadKeepAliveUpdateClosure keep_alive(task_queues()->queue(serial_worker_id)); + rp->process_discovered_references(&is_alive, &keep_alive, + &complete_gc, &executor, + NULL, _heap->shenandoah_policy()->tracer()->gc_id()); + } else { + ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure keep_alive(task_queues()->queue(serial_worker_id)); + rp->process_discovered_references(&is_alive, &keep_alive, + &complete_gc, &executor, + NULL, _heap->shenandoah_policy()->tracer()->gc_id()); + } + assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty"); + + { + ShenandoahGCPhase phase(phase_enqueue); + rp->enqueue_discovered_references(&executor); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_HPP + +#include "memory/allocation.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.hpp" +#include "gc_implementation/shenandoah/shenandoahHeapRegionSet.hpp" +#include "gc_implementation/shenandoah/shenandoahTaskqueue.hpp" +#include "runtime/thread.hpp" + +class ShenandoahTraversalGC : public CHeapObj { +private: + ShenandoahHeap* const _heap; + ShenandoahObjToScanQueueSet* const _task_queues; + ShenandoahHeapRegionSet _traversal_set; + +public: + ShenandoahTraversalGC(ShenandoahHeap* heap, size_t num_regions); + ~ShenandoahTraversalGC(); + + ShenandoahHeapRegionSet* traversal_set() { return &_traversal_set; } + + void reset(); + void prepare(); + void init_traversal_collection(); + void concurrent_traversal_collection(); + void final_traversal_collection(); + + template + inline void process_oop(T* p, Thread* thread, ShenandoahObjToScanQueue* queue, ShenandoahMarkingContext* const mark_context, ShenandoahStrDedupQueue* dq = NULL); + + ShenandoahObjToScanQueueSet* task_queues(); + + void main_loop(uint worker_id, ShenandoahTaskTerminator* terminator); + +private: + void prepare_regions(); + + template + void main_loop_work(T* cl, jushort* live_data, uint worker_id, ShenandoahTaskTerminator* terminator); + + void preclean_weak_refs(); + void weak_refs_work(); + void weak_refs_work_doit(); + + void fixup_roots(); +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.inline.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP + +#include "gc_implementation/shenandoah/shenandoahAsserts.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" +#include "gc_implementation/shenandoah/shenandoahStringDedup.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" +#include "gc_implementation/shenandoah/shenandoahTaskqueue.hpp" +#include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp" +#include "oops/oop.inline.hpp" + +template +void ShenandoahTraversalGC::process_oop(T* p, Thread* thread, ShenandoahObjToScanQueue* queue, ShenandoahMarkingContext* const mark_context, ShenandoahStrDedupQueue* dq) { + T o = oopDesc::load_heap_oop(p); + if (!oopDesc::is_null(o)) { + oop obj = oopDesc::decode_heap_oop_not_null(o); + if (DEGEN) { + assert(!ATOMIC_UPDATE, "Degen path assumes non-atomic updates"); + oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (obj != forw) { + // Update reference. + oopDesc::encode_store_heap_oop_not_null(p, forw); + } + obj = forw; + } else if (_heap->in_collection_set(obj)) { + oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (obj == forw) { + forw = _heap->evacuate_object(obj, thread); + } + shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc()); + // Update reference. + if (ATOMIC_UPDATE) { + _heap->cas_oop(forw, p, obj); + } else { + oopDesc::encode_store_heap_oop_not_null(p, forw); + } + obj = forw; + } + + shenandoah_assert_not_forwarded(p, obj); + shenandoah_assert_not_in_cset_except(p, obj, _heap->cancelled_gc()); + + if (mark_context->mark(obj)) { + bool succeeded = queue->push(ShenandoahMarkTask(obj)); + assert(succeeded, "must succeed to push to task queue"); + + if (STRING_DEDUP && ShenandoahStringDedup::is_candidate(obj) && !_heap->cancelled_gc()) { + assert(ShenandoahStringDedup::is_enabled(), "Must be enabled"); + // Only dealing with to-space string, so that we can avoid evac-oom protocol, which is costly here. + shenandoah_assert_not_in_cset(p, obj); + assert(dq != NULL, "Dedup queue not set"); + ShenandoahStringDedup::enqueue_candidate(obj, dq); + } + } + } +} + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahTraversalMode.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" + +void ShenandoahTraversalMode::initialize_flags() const { + FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); + FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true); + FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false); + FLAG_SET_DEFAULT(ShenandoahAllowMixedAllocs, false); + + SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); + SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); + + // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahStoreValEnqueueBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); +} + +ShenandoahHeuristics* ShenandoahTraversalMode::initialize_heuristics() const { + if (ShenandoahGCHeuristics != NULL) { + if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahTraversalHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahTraversalAggressiveHeuristics(); + } else { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); + } + } + ShouldNotReachHere(); + return NULL; +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalMode.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP + +#include "gc_implementation/shenandoah/shenandoahMode.hpp" + +class ShenandoahHeuristics; + +class ShenandoahTraversalMode : public ShenandoahMode { +public: + virtual void initialize_flags() const; + virtual ShenandoahHeuristics* initialize_heuristics() const; +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -125,6 +125,9 @@ case ShenandoahPhaseTimings::init_evac: case ShenandoahPhaseTimings::final_update_refs_roots: case ShenandoahPhaseTimings::degen_gc_update_roots: + case ShenandoahPhaseTimings::init_traversal_gc_work: + case ShenandoahPhaseTimings::final_traversal_gc_work: + case ShenandoahPhaseTimings::final_traversal_update_roots: case ShenandoahPhaseTimings::full_gc_roots: return true; default: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -100,6 +100,8 @@ return type == VM_Operation::VMOp_ShenandoahInitMark || type == VM_Operation::VMOp_ShenandoahFinalMarkStartEvac || type == VM_Operation::VMOp_ShenandoahFinalEvac || + type == VM_Operation::VMOp_ShenandoahInitTraversalGC || + type == VM_Operation::VMOp_ShenandoahFinalTraversalGC || type == VM_Operation::VMOp_ShenandoahInitUpdateRefs || type == VM_Operation::VMOp_ShenandoahFinalUpdateRefs || type == VM_Operation::VMOp_ShenandoahFullGC || diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -23,8 +23,8 @@ #include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahAsserts.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahRootProcessor.hpp" @@ -136,7 +136,7 @@ // skip break; case ShenandoahVerifier::_verify_liveness_complete: - Atomic::add(obj->size() + ShenandoahBrooksPointer::word_size(), &_ld[obj_reg->region_number()]); + Atomic::add((uint) obj->size(), &_ld[obj_reg->region_number()]); // fallthrough for fast failure for un-live regions: case ShenandoahVerifier::_verify_liveness_conservative: verify(ShenandoahAsserts::_safe_oop, obj, obj_reg->has_live(), @@ -147,11 +147,11 @@ } } - oop fwd = (oop) ShenandoahBrooksPointer::get_raw_unchecked(obj); + oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj); ShenandoahHeapRegion* fwd_reg = NULL; - if (!oopDesc::unsafe_equals(obj, fwd)) { + if (obj != fwd) { verify(ShenandoahAsserts::_safe_oop, obj, _heap->is_in(fwd), "Forwardee must be in heap"); verify(ShenandoahAsserts::_safe_oop, obj, !oopDesc::is_null(fwd), @@ -180,8 +180,8 @@ verify(ShenandoahAsserts::_safe_oop, obj, (fwd_addr + fwd->size()) <= fwd_reg->top(), "Forwardee end should be within the region"); - oop fwd2 = (oop) ShenandoahBrooksPointer::get_raw_unchecked(fwd); - verify(ShenandoahAsserts::_safe_oop, obj, oopDesc::unsafe_equals(fwd, fwd2), + oop fwd2 = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(fwd); + verify(ShenandoahAsserts::_safe_oop, obj, fwd == fwd2, "Double forwarding"); } else { fwd_reg = obj_reg; @@ -209,12 +209,12 @@ // skip break; case ShenandoahVerifier::_verify_forwarded_none: { - verify(ShenandoahAsserts::_safe_all, obj, oopDesc::unsafe_equals(obj, fwd), + verify(ShenandoahAsserts::_safe_all, obj, obj == fwd, "Should not be forwarded"); break; } case ShenandoahVerifier::_verify_forwarded_allow: { - if (!oopDesc::unsafe_equals(obj, fwd)) { + if (obj != fwd) { verify(ShenandoahAsserts::_safe_all, obj, obj_reg != fwd_reg, "Forwardee should be in another region"); } @@ -234,7 +234,7 @@ break; case ShenandoahVerifier::_verify_cset_forwarded: if (_heap->in_collection_set(obj)) { - verify(ShenandoahAsserts::_safe_all, obj, !oopDesc::unsafe_equals(obj, fwd), + verify(ShenandoahAsserts::_safe_all, obj, obj != fwd, "Object in collection set, should have forwardee"); } break; @@ -388,6 +388,27 @@ verify(r, r->is_cset() == _heap->collection_set()->is_in(r), "Transitional: region flags and collection set agree"); + + verify(r, r->is_empty() || r->seqnum_first_alloc() != 0, + "Non-empty regions should have first seqnum set"); + + verify(r, r->is_empty() || (r->seqnum_first_alloc_mutator() != 0 || r->seqnum_first_alloc_gc() != 0), + "Non-empty regions should have first seqnum set to either GC or mutator"); + + verify(r, r->is_empty() || r->seqnum_last_alloc() != 0, + "Non-empty regions should have last seqnum set"); + + verify(r, r->is_empty() || (r->seqnum_last_alloc_mutator() != 0 || r->seqnum_last_alloc_gc() != 0), + "Non-empty regions should have last seqnum set to either GC or mutator"); + + verify(r, r->seqnum_first_alloc() <= r->seqnum_last_alloc(), + "First seqnum should not be greater than last timestamp"); + + verify(r, r->seqnum_first_alloc_mutator() <= r->seqnum_last_alloc_mutator(), + "First mutator seqnum should not be greater than last seqnum"); + + verify(r, r->seqnum_first_alloc_gc() <= r->seqnum_last_alloc_gc(), + "First GC seqnum should not be greater than last seqnum"); } }; @@ -504,7 +525,7 @@ virtual void work_humongous(ShenandoahHeapRegion *r, ShenandoahVerifierStack& stack, ShenandoahVerifyOopClosure& cl) { jlong processed = 0; - HeapWord* obj = r->bottom() + ShenandoahBrooksPointer::word_size(); + HeapWord* obj = r->bottom(); if (_heap->complete_marking_context()->is_marked((oop)obj)) { verify_and_follow(obj, stack, cl, &processed); } @@ -518,12 +539,12 @@ // Bitmaps, before TAMS if (tams > r->bottom()) { - HeapWord* start = r->bottom() + ShenandoahBrooksPointer::word_size(); + HeapWord* start = r->bottom(); HeapWord* addr = mark_bit_map->getNextMarkedWordAddress(start, tams); while (addr < tams) { verify_and_follow(addr, stack, cl, &processed); - addr += ShenandoahBrooksPointer::word_size(); + addr += 1; if (addr < tams) { addr = mark_bit_map->getNextMarkedWordAddress(addr, tams); } @@ -533,11 +554,11 @@ // Size-based, after TAMS { HeapWord* limit = r->top(); - HeapWord* addr = tams + ShenandoahBrooksPointer::word_size(); + HeapWord* addr = tams; while (addr < limit) { verify_and_follow(addr, stack, cl, &processed); - addr += oop(addr)->size() + ShenandoahBrooksPointer::word_size(); + addr += oop(addr)->size(); } } @@ -637,13 +658,17 @@ _heap->heap_region_iterate(&cl); size_t heap_used = _heap->used(); guarantee(cl.used() == heap_used, - err_msg("%s: heap used size must be consistent: heap-used = " SIZE_FORMAT "K, regions-used = " SIZE_FORMAT "K", - label, heap_used/K, cl.used()/K)); + err_msg("%s: heap used size must be consistent: heap-used = " SIZE_FORMAT "%s, regions-used = " SIZE_FORMAT "%s", + label, + byte_size_in_proper_unit(heap_used), proper_unit_for_byte_size(heap_used), + byte_size_in_proper_unit(cl.used()), proper_unit_for_byte_size(cl.used()))); size_t heap_committed = _heap->committed(); guarantee(cl.committed() == heap_committed, - err_msg("%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "K, regions-committed = " SIZE_FORMAT "K", - label, heap_committed/K, cl.committed()/K)); + err_msg("%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "%s, regions-committed = " SIZE_FORMAT "%s", + label, + byte_size_in_proper_unit(heap_committed), proper_unit_for_byte_size(heap_committed), + byte_size_in_proper_unit(cl.committed()), proper_unit_for_byte_size(cl.committed()))); } // Internal heap region checks @@ -837,6 +862,30 @@ ); } +void ShenandoahVerifier::verify_before_traversal() { + verify_at_safepoint( + "Before Traversal", + _verify_forwarded_none, // cannot have forwarded objects + _verify_marked_disable, // bitmaps are not relevant before traversal + _verify_cset_none, // no cset references before traversal + _verify_liveness_disable, // no reliable liveness data anymore + _verify_regions_notrash_nocset, // no trash and no cset regions + _verify_gcstate_stable // nothing forwarded before traversal + ); +} + +void ShenandoahVerifier::verify_after_traversal() { + verify_at_safepoint( + "After Traversal", + _verify_forwarded_none, // cannot have forwarded objects + _verify_marked_complete, // should have complete marking after traversal + _verify_cset_none, // no cset references left after traversal + _verify_liveness_disable, // liveness data is not collected for new allocations + _verify_regions_nocset, // no cset regions, trash regions allowed + _verify_gcstate_stable // nothing forwarded after traversal + ); +} + void ShenandoahVerifier::verify_before_fullgc() { verify_at_safepoint( "Before Full GC", diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVerifier.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -178,6 +178,8 @@ void verify_after_updaterefs(); void verify_before_fullgc(); void verify_after_fullgc(); + void verify_before_traversal(); + void verify_after_traversal(); void verify_after_degenerated(); void verify_generic(VerifyOption option); }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -66,6 +66,16 @@ ShenandoahHeap::heap()->entry_full(_gc_cause); } +void VM_ShenandoahInitTraversalGC::doit() { + ShenandoahGCPauseMark mark(SvcGCMarker::OTHER); + ShenandoahHeap::heap()->entry_init_traversal(); +} + +void VM_ShenandoahFinalTraversalGC::doit() { + ShenandoahGCPauseMark mark(SvcGCMarker::OTHER); + ShenandoahHeap::heap()->entry_final_traversal(); +} + void VM_ShenandoahInitUpdateRefs::doit() { ShenandoahGCPauseMark mark(SvcGCMarker::OTHER); ShenandoahHeap::heap()->entry_init_updaterefs(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahVMOperations.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -36,6 +36,8 @@ // - VM_ShenandoahInitUpdateRefs: initiate update references // - VM_ShenandoahFinalUpdateRefs: finish up update references // - VM_ShenandoahFullGC: do full GC +// - VM_ShenandoahInitTraversalGC: init traversal GC +// - VM_ShenandoahFinalTraversalGC: finish traversal GC class VM_ShenandoahOperation : public VM_Operation { public: @@ -99,6 +101,22 @@ virtual void doit(); }; +class VM_ShenandoahInitTraversalGC: public VM_ShenandoahOperation { +public: + VM_ShenandoahInitTraversalGC() : VM_ShenandoahOperation() {}; + VM_Operation::VMOp_Type type() const { return VMOp_ShenandoahInitTraversalGC; } + const char* name() const { return "Shenandoah Init Traversal Collection"; } + virtual void doit(); +}; + +class VM_ShenandoahFinalTraversalGC: public VM_ShenandoahReferenceOperation { +public: + VM_ShenandoahFinalTraversalGC() : VM_ShenandoahReferenceOperation() {}; + VM_Operation::VMOp_Type type() const { return VMOp_ShenandoahFinalTraversalGC; } + const char* name() const { return "Shenandoah Final Traversal Collection"; } + virtual void doit(); +}; + class VM_ShenandoahInitUpdateRefs: public VM_ShenandoahOperation { public: VM_ShenandoahInitUpdateRefs() : VM_ShenandoahOperation() {}; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,6 +32,8 @@ uint ShenandoahWorkerPolicy::_prev_conc_evac = 0; uint ShenandoahWorkerPolicy::_prev_fullgc = 0; uint ShenandoahWorkerPolicy::_prev_degengc = 0; +uint ShenandoahWorkerPolicy::_prev_stw_traversal = 0; +uint ShenandoahWorkerPolicy::_prev_conc_traversal = 0; uint ShenandoahWorkerPolicy::_prev_conc_update_ref = 0; uint ShenandoahWorkerPolicy::_prev_par_update_ref = 0; uint ShenandoahWorkerPolicy::_prev_conc_cleanup = 0; @@ -81,6 +83,26 @@ return _prev_fullgc; } +// Calculate workers for Stop-the-world traversal GC +uint ShenandoahWorkerPolicy::calc_workers_for_stw_traversal() { + uint active_workers = (_prev_stw_traversal == 0) ? ParallelGCThreads : _prev_stw_traversal; + _prev_stw_traversal = + AdaptiveSizePolicy::calc_active_workers(ParallelGCThreads, + active_workers, + Threads::number_of_non_daemon_threads()); + return _prev_stw_traversal; +} + +// Calculate workers for concurent traversal GC +uint ShenandoahWorkerPolicy::calc_workers_for_conc_traversal() { + uint active_workers = (_prev_conc_traversal == 0) ? ConcGCThreads : _prev_conc_traversal; + _prev_conc_traversal = + AdaptiveSizePolicy::calc_active_conc_workers(ConcGCThreads, + active_workers, + Threads::number_of_non_daemon_threads()); + return _prev_conc_traversal; +} + // Calculate workers for concurrent reference update uint ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref() { uint active_workers = (_prev_conc_update_ref == 0) ? ConcGCThreads : _prev_conc_update_ref; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/shenandoahWorkerPolicy.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -33,6 +33,8 @@ static uint _prev_conc_evac; static uint _prev_fullgc; static uint _prev_degengc; + static uint _prev_stw_traversal; + static uint _prev_conc_traversal; static uint _prev_conc_update_ref; static uint _prev_par_update_ref; static uint _prev_conc_cleanup; @@ -57,6 +59,12 @@ // Calculate workers for parallel degenerated gc static uint calc_workers_for_stw_degenerated(); + // Calculate workers for Stop-the-world traversal GC + static uint calc_workers_for_stw_traversal(); + + // Calculate workers for concurrent traversal GC + static uint calc_workers_for_conc_traversal(); + // Calculate workers for concurrent reference update static uint calc_workers_for_conc_update_ref(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/vmStructs_shenandoah.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/vmStructs_shenandoah.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/vmStructs_shenandoah.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_implementation/shenandoah/vmStructs_shenandoah.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -30,6 +30,7 @@ #define VM_STRUCTS_SHENANDOAH(nonstatic_field, volatile_nonstatic_field, static_field) \ static_field(ShenandoahHeapRegion, RegionSizeBytes, size_t) \ nonstatic_field(ShenandoahHeap, _num_regions, size_t) \ + nonstatic_field(ShenandoahHeap, _regions, ShenandoahHeapRegion**) \ volatile_nonstatic_field(ShenandoahHeap, _used, jlong) \ volatile_nonstatic_field(ShenandoahHeap, _committed, size_t) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -302,7 +302,7 @@ #endif // ASSERT } thread->tlab().fill(obj, obj + size, new_tlab_size); - return Universe::heap()->tlab_post_allocation_setup(obj); + return obj; } void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) { @@ -609,15 +609,6 @@ } #endif -HeapWord* CollectedHeap::tlab_post_allocation_setup(HeapWord* obj) { - return obj; -} - -uint CollectedHeap::oop_extra_words() { - // Default implementation doesn't need extra space for oops. - return 0; -} - void CollectedHeap::shutdown() { // Default implementation does nothing. } @@ -626,12 +617,6 @@ // Default implementation does nothing. } -#ifndef CC_INTERP -void CollectedHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { - // Default implementation does nothing. -} -#endif - bool CollectedHeap::supports_object_pinning() const { return false; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -199,8 +199,6 @@ virtual CollectedHeap::Name kind() const { return CollectedHeap::Abstract; } - virtual HeapWord* tlab_post_allocation_setup(HeapWord* obj); - /** * Returns JNI error code JNI_ENOMEM if memory could not be allocated, * and JNI_OK on success. @@ -327,12 +325,6 @@ inline static void post_allocation_install_obj_klass(KlassHandle klass, oop obj); - virtual uint oop_extra_words(); - -#ifndef CC_INTERP - virtual void compile_prepare_oop(MacroAssembler* masm, Register obj); -#endif - // Raw memory allocation facilities // The obj and array allocate methods are covers for these methods. // mem_allocate() should never be diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/collectedHeap.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -50,10 +50,10 @@ assert(obj != NULL, "NULL object pointer"); if (UseBiasedLocking && (klass() != NULL)) { - obj->set_mark_raw(klass->prototype_header()); + obj->set_mark(klass->prototype_header()); } else { // May be bootstrapping - obj->set_mark_raw(markOopDesc::prototype()); + obj->set_mark(markOopDesc::prototype()); } } @@ -180,10 +180,8 @@ HeapWord* CollectedHeap::allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size) { assert(UseTLAB, "should use UseTLAB"); - size += Universe::heap()->oop_extra_words(); HeapWord* obj = thread->tlab().allocate(size); if (obj != NULL) { - obj = Universe::heap()->tlab_post_allocation_setup(obj); return obj; } // Otherwise... diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/gcCause.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/gcCause.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/gc_interface/gcCause.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/gc_interface/gcCause.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -77,6 +77,7 @@ _shenandoah_metadata_gc_clear_softrefs, _shenandoah_allocation_failure_evac, _shenandoah_concurrent_gc, + _shenandoah_traversal_gc, _shenandoah_upgrade_to_full_gc, _last_ditch_collection, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/interpreter/interpreterRuntime.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/interpreter/interpreterRuntime.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/interpreter/interpreterRuntime.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/interpreter/interpreterRuntime.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -139,7 +139,7 @@ // The bytecode wrappers aren't GC-safe so construct a new one Bytecode_loadconstant ldc2(m, bci(thread)); oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index()); - assert(oopDesc::equals(result, coop), "expected result for assembly code"); + assert(result == coop, "expected result for assembly code"); } #endif thread->set_vm_result(result); @@ -615,7 +615,7 @@ if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } - Handle h_obj(thread, oopDesc::bs()->write_barrier(elem->obj())); + Handle h_obj(thread, elem->obj()); assert(Universe::heap()->is_in_reserved_or_null(h_obj()), "must be NULL or an object"); if (UseBiasedLocking) { @@ -637,7 +637,7 @@ #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif - Handle h_obj(thread, oopDesc::bs()->write_barrier(elem->obj())); + Handle h_obj(thread, elem->obj()); assert(Universe::heap()->is_in_reserved_or_null(h_obj()), "must be NULL or an object"); if (elem == NULL || h_obj()->is_unlocked()) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/barrierSet.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/barrierSet.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/barrierSet.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/barrierSet.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -73,12 +73,3 @@ // simply delegate to instance method Universe::heap()->barrier_set()->write_ref_array(start, count); } - -bool BarrierSet::obj_equals(oop obj1, oop obj2) { - return oopDesc::unsafe_equals(obj1, obj2); -} - -bool BarrierSet::obj_equals(narrowOop obj1, narrowOop obj2) { - return oopDesc::unsafe_equals(obj1, obj2); -} - diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/barrierSet.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/barrierSet.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/barrierSet.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/barrierSet.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,13 +27,10 @@ #include "memory/memRegion.hpp" #include "oops/oopsHierarchy.hpp" -#include "asm/register.hpp" // This class provides the interface between a barrier implementation and // the rest of the system. -class MacroAssembler; - class BarrierSet: public CHeapObj { friend class VMStructs; public: @@ -186,34 +183,6 @@ // Print a description of the memory for the barrier set virtual void print_on(outputStream* st) const = 0; - - virtual oop read_barrier(oop src) { - return src; - } - virtual oop write_barrier(oop src) { - return src; - } - - virtual bool obj_equals(oop obj1, oop obj2); - - virtual bool obj_equals(narrowOop obj1, narrowOop obj2); - -#ifndef CC_INTERP - virtual void interpreter_read_barrier(MacroAssembler* masm, Register dst) { - // Default implementation does nothing. - } - - virtual void interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { - // Default implementation does nothing. - } - - virtual void interpreter_write_barrier(MacroAssembler* masm, Register dst) { - // Default implementation does nothing. - } - virtual void asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { - // Default implementation does nothing. - } -#endif }; #endif // SHARE_VM_MEMORY_BARRIERSET_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/binaryTreeDictionary.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/binaryTreeDictionary.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/binaryTreeDictionary.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/binaryTreeDictionary.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,6 +27,7 @@ #include "memory/freeBlockDictionary.hpp" #include "memory/freeList.hpp" +#include "memory/memRegion.hpp" /* * A binary tree based search structure for free blocks. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/gcLocker.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/gcLocker.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/gcLocker.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/gcLocker.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -31,6 +31,7 @@ volatile jint GC_locker::_jni_lock_count = 0; volatile bool GC_locker::_needs_gc = false; volatile bool GC_locker::_doing_gc = false; +unsigned int GC_locker::_total_collections = 0; #ifdef ASSERT volatile jint GC_locker::_debug_jni_lock_count = 0; @@ -94,6 +95,11 @@ } } +bool GC_locker::should_discard(GCCause::Cause cause, uint total_collections) { + return (cause == GCCause::_gc_locker) && + (_total_collections != total_collections); +} + void GC_locker::jni_lock(JavaThread* thread) { assert(!thread->in_critical(), "shouldn't currently be in a critical region"); MutexLocker mu(JNICritical_lock); @@ -117,7 +123,13 @@ decrement_debug_jni_lock_count(); thread->exit_critical(); if (needs_gc() && !is_active_internal()) { - // We're the last thread out. Cause a GC to occur. + // We're the last thread out. Request a GC. + // Capture the current total collections, to allow detection of + // other collections that make this one unnecessary. The value of + // total_collections() is only changed at a safepoint, so there + // must not be a safepoint between the lock becoming inactive and + // getting the count, else there may be unnecessary GCLocker GCs. + _total_collections = Universe::heap()->total_collections(); _doing_gc = true; { // Must give up the lock while at a safepoint diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/gcLocker.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/gcLocker.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/gcLocker.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/gcLocker.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,6 +26,7 @@ #define SHARE_VM_MEMORY_GCLOCKER_HPP #include "gc_interface/collectedHeap.hpp" +#include "gc_interface/gcCause.hpp" #include "memory/genCollectedHeap.hpp" #include "memory/universe.hpp" #include "oops/oop.hpp" @@ -57,6 +58,7 @@ static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC + static uint _total_collections; // value for _gc_locker collection #ifdef ASSERT // This lock count is updated for all operations and is used to @@ -116,6 +118,12 @@ // Sets _needs_gc if is_active() is true. Returns is_active(). static bool check_active_before_gc(); + // Return true if the designated collection is a GCLocker request + // that should be discarded. Returns true if cause == GCCause::_gc_locker + // and the given total collection value indicates a collection has been + // done since the GCLocker request was made. + static bool should_discard(GCCause::Cause cause, uint total_collections); + // Stalls the caller (who should not be in a jni critical section) // until needs_gc() clears. Note however that needs_gc() may be // set at a subsequent safepoint and/or cleared under the diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/genCollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/genCollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/genCollectedHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/genCollectedHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -796,8 +796,11 @@ #else // INCLUDE_ALL_GCS ShouldNotReachHere(); #endif // INCLUDE_ALL_GCS - } else if (cause == GCCause::_wb_young_gc) { - // minor collection for WhiteBox API + } else if ((cause == GCCause::_wb_young_gc) || + (cause == GCCause::_gc_locker)) { + // minor collection for WhiteBox or GCLocker. + // _gc_locker collections upgraded by GCLockerInvokesConcurrent + // are handled above and never discarded. collect(cause, 0); } else { #ifdef ASSERT @@ -835,6 +838,11 @@ // Read the GC count while holding the Heap_lock unsigned int gc_count_before = total_collections(); unsigned int full_gc_count_before = total_full_collections(); + + if (GC_locker::should_discard(cause, gc_count_before)) { + return; + } + { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back VM_GenCollectFull op(gc_count_before, full_gc_count_before, @@ -887,24 +895,16 @@ void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, int max_level) { - int local_max_level; - if (!incremental_collection_will_fail(false /* don't consult_young */) && - gc_cause() == GCCause::_gc_locker) { - local_max_level = 0; - } else { - local_max_level = max_level; - } do_collection(true /* full */, clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - local_max_level /* max_level */); + max_level /* max_level */); // Hack XXX FIX ME !!! // A scavenge may not have been attempted, or may have // been attempted and failed, because the old gen was too full - if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker && - incremental_collection_will_fail(false /* don't consult_young */)) { + if (gc_cause() == GCCause::_gc_locker && incremental_collection_failed()) { if (PrintGCDetails) { gclog_or_tty->print_cr("GC locker: Trying a full collection " "because scavenge failed"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/generation.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/generation.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/generation.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/generation.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -68,6 +68,12 @@ return gch->_gen_specs[level()]; } +// This is for CMS. It returns stable monotonic used space size. +// Remove this when CMS is removed. +size_t Generation::used_stable() const { + return used(); +} + size_t Generation::max_capacity() const { return reserved().byte_size(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/generation.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/generation.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/generation.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/generation.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -168,6 +168,7 @@ virtual size_t capacity() const = 0; // The maximum number of object bytes the // generation can currently hold. virtual size_t used() const = 0; // The number of used bytes in the gen. + virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools. virtual size_t free() const = 0; // The number of free bytes in the gen. // Support for java.lang.Runtime.maxMemory(); see CollectedHeap. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -323,7 +323,7 @@ ref->disable_discovery(); // Return true if new pending references were added - return ! oopDesc::unsafe_equals(old_pending_list_value, *pending_list_addr); + return old_pending_list_value != *pending_list_addr; } bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) { @@ -363,7 +363,7 @@ if (pending_list_uses_discovered_field()) { // New behavior // Walk down the list, self-looping the next field // so that the References are not considered active. - while (! oopDesc::unsafe_equals(obj, next_d)) { + while (obj != next_d) { obj = next_d; assert(obj->is_instanceRef(), "should be reference object"); next_d = java_lang_ref_Reference::discovered(obj); @@ -375,7 +375,7 @@ "Reference not active; should not be discovered"); // Self-loop next, so as to make Ref not active. java_lang_ref_Reference::set_next_raw(obj, obj); - if (! oopDesc::unsafe_equals(next_d, obj)) { + if (next_d != obj) { oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d); } else { // This is the last object. @@ -493,7 +493,7 @@ // First _prev_next ref actually points into DiscoveredList (gross). oop new_next; - if (oopDesc::unsafe_equals(_next, _ref)) { + if (_next == _ref) { // At the end of the list, we should make _prev point to itself. // If _ref is the first ref, then _prev_next will be in the DiscoveredList, // and _prev will be NULL. @@ -697,7 +697,7 @@ ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) { oop obj = NULL; oop next = refs_list.head(); - while (! oopDesc::unsafe_equals(next, obj)) { + while (next != obj) { obj = next; next = java_lang_ref_Reference::discovered(obj); java_lang_ref_Reference::set_discovered_raw(obj, NULL); @@ -849,7 +849,7 @@ ref_lists[to_idx].inc_length(refs_to_move); // Remove the chain from the from list. - if (oopDesc::unsafe_equals(move_tail, new_head)) { + if (move_tail == new_head) { // We found the end of the from list. ref_lists[from_idx].set_head(NULL); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/referenceProcessor.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -197,13 +197,13 @@ ) inline void move_to_next() { - if (oopDesc::unsafe_equals(_ref, _next)) { + if (_ref == _next) { // End of the list. _ref = NULL; } else { _ref = _next; } - assert(! oopDesc::unsafe_equals(_ref, _first_seen), "cyclic ref_list found"); + assert(_ref != _first_seen, "cyclic ref_list found"); NOT_PRODUCT(_processed++); } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/sharedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/sharedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/sharedHeap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/sharedHeap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -50,7 +50,7 @@ if ((UseParNewGC || (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || CMSParallelRemarkEnabled)) || - UseG1GC || UseShenandoahGC) && + UseG1GC) && ParallelGCThreads > 0) { _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads, /* are_GC_task_threads */true, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -124,8 +124,7 @@ } } - HeapWord* obj = Universe::heap()->tlab_post_allocation_setup(top()); - CollectedHeap::fill_with_object(obj, hard_end(), retire); + CollectedHeap::fill_with_object(top(), hard_end(), retire); if (retire || ZeroTLAB) { // "Reset" the TLAB set_start(NULL); @@ -310,11 +309,6 @@ return thread; } -size_t ThreadLocalAllocBuffer::end_reserve() { - int reserve_size = typeArrayOopDesc::header_size(T_INT) + Universe::heap()->oop_extra_words(); - return MAX2(reserve_size, VM_Version::reserve_for_allocation_prefetch()); -} - void ThreadLocalAllocBuffer::rollback(size_t size) { HeapWord* old_top = top(); if (old_top != NULL) { // Pathological case: we accept that we can't rollback. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/threadLocalAllocBuffer.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -123,6 +123,12 @@ // Allocate size HeapWords. The memory is NOT initialized to zero. inline HeapWord* allocate(size_t size); + // Reserve space at the end of TLAB + static size_t end_reserve() { + int reserve_size = typeArrayOopDesc::header_size(T_INT); + return MAX2(reserve_size, VM_Version::reserve_for_allocation_prefetch()); + } + // Resize based on amount of allocation, etc. void resize(); @@ -132,7 +138,6 @@ // Rolls back a single allocation of the given size. void rollback(size_t size); - static size_t end_reserve(); static size_t alignment_reserve() { return align_object_size(end_reserve()); } static size_t alignment_reserve_in_bytes() { return alignment_reserve() * HeapWordSize; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/universe.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/universe.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/memory/universe.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/memory/universe.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -576,12 +576,12 @@ // preallocated errors with backtrace have been consumed. Also need to avoid // a potential loop which could happen if an out of memory occurs when attempting // to allocate the backtrace. - return ((!oopDesc::equals(throwable(), Universe::_out_of_memory_error_java_heap)) && - (!oopDesc::equals(throwable(), Universe::_out_of_memory_error_metaspace)) && - (!oopDesc::equals(throwable(), Universe::_out_of_memory_error_class_metaspace)) && - (!oopDesc::equals(throwable(), Universe::_out_of_memory_error_array_size)) && - (!oopDesc::equals(throwable(), Universe::_out_of_memory_error_gc_overhead_limit)) && - (!oopDesc::equals(throwable(), Universe::_out_of_memory_error_realloc_objects))); + return ((throwable() != Universe::_out_of_memory_error_java_heap) && + (throwable() != Universe::_out_of_memory_error_metaspace) && + (throwable() != Universe::_out_of_memory_error_class_metaspace) && + (throwable() != Universe::_out_of_memory_error_array_size) && + (throwable() != Universe::_out_of_memory_error_gc_overhead_limit) && + (throwable() != Universe::_out_of_memory_error_realloc_objects)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/instanceKlass.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/instanceKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/instanceKlass.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/instanceKlass.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -295,6 +295,7 @@ set_has_unloaded_dependent(false); set_init_state(InstanceKlass::allocated); set_init_thread(NULL); + set_init_state(allocated); set_reference_type(rt); set_oop_map_cache(NULL); set_jni_ids(NULL); @@ -979,11 +980,13 @@ oop init_lock = this_oop->init_lock(); if (init_lock != NULL) { ObjectLocker ol(init_lock, THREAD); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); this_oop->fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(init_lock != NULL, "The initialization state should never be set twice"); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); } } @@ -2619,7 +2622,7 @@ } address InstanceKlass::static_field_addr(int offset) { - return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop(oopDesc::bs()->write_barrier(java_mirror()))); + return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop(java_mirror())); } @@ -2696,7 +2699,7 @@ // and classname information is enough to determine a class's package bool InstanceKlass::is_same_class_package(oop class_loader1, Symbol* class_name1, oop class_loader2, Symbol* class_name2) { - if (! oopDesc::equals(class_loader1, class_loader2)) { + if (class_loader1 != class_loader2) { return false; } else if (class_name1 == class_name2) { return true; // skip painful bytewise comparison @@ -3603,6 +3606,7 @@ bool good_state = is_shared() ? (_init_state <= state) : (_init_state < state); assert(good_state || state == allocated, "illegal state transition"); + assert(_init_thread == NULL, "should be cleared before state change"); _init_state = (u1)state; } #endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/instanceKlass.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/instanceKlass.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/instanceKlass.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/instanceKlass.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -241,7 +241,7 @@ u2 _misc_flags; u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file - Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) + Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/klassVtable.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/klassVtable.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/klassVtable.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/klassVtable.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -289,22 +289,25 @@ int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { InstanceKlass* superk = initialsuper; while (superk != NULL && superk->super() != NULL) { - InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); - klassVtable* ssVtable = supersuperklass->vtable(); + klassVtable* ssVtable = (superk->super())->vtable(); if (vtable_index < ssVtable->length()) { Method* super_method = ssVtable->method_at(vtable_index); + // get the class holding the matching method + // make sure you use that class for is_override + InstanceKlass* supermethodholder = super_method->method_holder(); #ifndef PRODUCT Symbol* name= target_method()->name(); Symbol* signature = target_method()->signature(); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif - if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { + + if (supermethodholder->is_override(super_method, target_loader, target_classname, THREAD)) { #ifndef PRODUCT if (PrintVtables && Verbose) { ResourceMark rm(THREAD); char* sig = target_method()->name_and_sig_as_C_string(); tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", - supersuperklass->internal_name(), + supermethodholder->internal_name(), _klass->internal_name(), sig, vtable_index); super_method->access_flags().print_on(tty); if (super_method->is_default_method()) { @@ -458,7 +461,7 @@ // to link to the first super, and we get all the others. Handle super_loader(THREAD, super_klass->class_loader()); - if (! oopDesc::equals(target_loader(), super_loader())) { + if (target_loader() != super_loader()) { ResourceMark rm(THREAD); Symbol* failed_type_symbol = SystemDictionary::check_signature_loaders(signature, target_loader, @@ -656,7 +659,7 @@ // search through the super class hierarchy to see if we need // a new entry - ResourceMark rm; + ResourceMark rm(THREAD); Symbol* name = target_method()->name(); Symbol* signature = target_method()->signature(); Klass* k = super; @@ -1247,7 +1250,7 @@ // if checkconstraints requested if (checkconstraints) { Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); - if (! oopDesc::equals(method_holder_loader(), interface_loader())) { + if (method_holder_loader() != interface_loader()) { ResourceMark rm(THREAD); Symbol* failed_type_symbol = SystemDictionary::check_signature_loaders(m->signature(), diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/objArrayKlass.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/objArrayKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/objArrayKlass.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/objArrayKlass.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -244,7 +244,7 @@ assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); - if (oopDesc::equals(s, d)) { + if (s == d) { // since source and destination are equal we do not need conversion checks. assert(length > 0, "sanity check"); bs->write_ref_array_pre(dst, length); @@ -314,10 +314,6 @@ if (length==0) { return; } - - s = arrayOop(oopDesc::bs()->read_barrier(s)); - d = arrayOop(oopDesc::bs()->write_barrier(d)); - if (UseCompressedOops) { narrowOop* const src = objArrayOop(s)->obj_at_addr(src_pos); narrowOop* const dst = objArrayOop(d)->obj_at_addr(dst_pos); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/objArrayOop.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/objArrayOop.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/objArrayOop.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/objArrayOop.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,6 +28,10 @@ #include "memory/barrierSet.hpp" #include "oops/arrayOop.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#endif + // An objArrayOop is an array containing oops. // Evaluating "String arg[10]" will create an objArrayOop. @@ -80,23 +84,27 @@ // Accessing oop obj_at(int index) const { - objArrayOop p = (objArrayOop) oopDesc::bs()->read_barrier((oop) this); + oop obj; // With UseCompressedOops decode the narrow oop in the objArray to an // uncompressed oop. Otherwise this is simply a "*" operator. if (UseCompressedOops) { - return load_decode_heap_oop(p->obj_at_addr(index)); + obj = load_decode_heap_oop(obj_at_addr(index)); } else { - return load_decode_heap_oop(p->obj_at_addr(index)); + obj = load_decode_heap_oop(obj_at_addr(index)); + } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + obj = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(obj); } +#endif + return obj; } void obj_at_put(int index, oop value) { - objArrayOop p = (objArrayOop) oopDesc::bs()->write_barrier(this); - value = oopDesc::bs()->read_barrier(value); if (UseCompressedOops) { - oop_store(p->obj_at_addr(index), value); + oop_store(obj_at_addr(index), value); } else { - oop_store(p->obj_at_addr(index), value); + oop_store(obj_at_addr(index), value); } } // Sizing diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oop.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oop.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oop.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oop.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OOPS_OOP_HPP #define SHARE_VM_OOPS_OOP_HPP -#include "memory/barrierSet.hpp" #include "memory/iterator.hpp" #include "memory/memRegion.hpp" #include "memory/specialized_oop_closures.hpp" @@ -51,6 +50,7 @@ class ScanClosure; class FastScanClosure; class FilteringClosure; +class BarrierSet; class CMSIsAliveClosure; class PSPromotionManager; @@ -69,20 +69,10 @@ static BarrierSet* _bs; public: - markOop mark() const { - oop p = bs()->read_barrier((oop) this); - return p->_mark; - } + markOop mark() const { return _mark; } markOop* mark_addr() const { return (markOop*) &_mark; } - void set_mark(volatile markOop m) { - oop p = bs()->write_barrier(this); - p->_mark = m; - } - - void set_mark_raw(volatile markOop m) { - _mark = m; - } + void set_mark(volatile markOop m) { _mark = m; } void release_set_mark(markOop m); markOop cas_set_mark(markOop new_mark, markOop old_mark); @@ -152,26 +142,6 @@ static bool is_null(narrowOop obj); static bool is_null(Klass* obj); - inline static bool equals(oop o1, oop o2) { - return bs()->obj_equals(o1, o2); - } - - inline static bool equals(narrowOop o1, narrowOop o2) { - return bs()->obj_equals(o1, o2); - } - - inline static bool unsafe_equals(oop o1, oop o2) { -#ifdef CHECK_UNHANDLED_OOPS - return o1.obj() == o2.obj(); -#else - return o1 == o2; -#endif - } - - inline static bool unsafe_equals(narrowOop o1, narrowOop o2) { - return o1 == o2; - } - // Decode an oop pointer from a narrowOop if compressed. // These are overloaded for oop and narrowOop as are the other functions // below so that they can be called in template functions. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oop.inline.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oop.inline.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oop.inline.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oop.inline.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -61,17 +61,19 @@ # include "bytes_ppc.hpp" #endif +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" +#endif + // Implementation of all inlined member functions defined in oop.hpp // We need a separate file to avoid circular references inline void oopDesc::release_set_mark(markOop m) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store_ptr(&p->_mark, m); + OrderAccess::release_store_ptr(&_mark, m); } inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { - oop p = bs()->write_barrier(this); - return (markOop) Atomic::cmpxchg_ptr(new_mark, &p->_mark, old_mark); + return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark); } inline Klass* oopDesc::klass() const { @@ -203,7 +205,7 @@ assert(OopEncodingHeapMax > pd, "change encoding max if new encoding"); uint64_t result = pd >> shift; assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow"); - assert(oopDesc::unsafe_equals(decode_heap_oop(result), v), "reversibility"); + assert(decode_heap_oop(result) == v, "reversibility"); return (narrowOop)result; } @@ -293,24 +295,39 @@ // These functions are only used to exchange oop fields in instances, // not headers. inline oop oopDesc::atomic_exchange_oop(oop exchange_value, volatile HeapWord *dest) { + oop result; if (UseCompressedOops) { // encode exchange value from oop to T narrowOop val = encode_heap_oop(exchange_value); narrowOop old = (narrowOop)Atomic::xchg(val, (narrowOop*)dest); // decode old from T to oop - return decode_heap_oop(old); + result = decode_heap_oop(old); } else { - return (oop)Atomic::xchg_ptr(exchange_value, (oop*)dest); + result = (oop)Atomic::xchg_ptr(exchange_value, (oop*)dest); + } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + if (exchange_value != NULL) { + ShenandoahBarrierSet::barrier_set()->storeval_barrier(exchange_value); + } + result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(result); } +#endif + return result; } // In order to put or get a field out of an instance, must first check // if the field has been compressed and uncompress it. inline oop oopDesc::obj_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return UseCompressedOops ? - load_decode_heap_oop(p->obj_field_addr(offset)) : - load_decode_heap_oop(p->obj_field_addr(offset)); + oop obj = UseCompressedOops ? + load_decode_heap_oop(obj_field_addr(offset)) : + load_decode_heap_oop(obj_field_addr(offset)); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + obj = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(obj); + } +#endif + return obj; } inline volatile oop oopDesc::obj_field_volatile(int offset) const { volatile oop value = obj_field(offset); @@ -318,28 +335,22 @@ return value; } inline void oopDesc::obj_field_put(int offset, oop value) { - oop p = bs()->write_barrier(this); - value = bs()->read_barrier(value); - UseCompressedOops ? oop_store(p->obj_field_addr(offset), value) : - oop_store(p->obj_field_addr(offset), value); + UseCompressedOops ? oop_store(obj_field_addr(offset), value) : + oop_store(obj_field_addr(offset), value); } inline Metadata* oopDesc::metadata_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->metadata_field_addr(offset); + return *metadata_field_addr(offset); } inline void oopDesc::metadata_field_put(int offset, Metadata* value) { - oop p = bs()->write_barrier(this); - *p->metadata_field_addr(offset) = value; + *metadata_field_addr(offset) = value; } inline void oopDesc::obj_field_put_raw(int offset, oop value) { - oop p = bs()->write_barrier(this); - value = bs()->read_barrier(value); UseCompressedOops ? - encode_store_heap_oop(p->obj_field_addr(offset), value) : - encode_store_heap_oop(p->obj_field_addr(offset), value); + encode_store_heap_oop(obj_field_addr(offset), value) : + encode_store_heap_oop(obj_field_addr(offset), value); } inline void oopDesc::obj_field_put_volatile(int offset, oop value) { OrderAccess::release(); @@ -347,186 +358,78 @@ OrderAccess::fence(); } -inline jbyte oopDesc::byte_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (jbyte) *p->byte_field_addr(offset); -} -inline void oopDesc::byte_field_put(int offset, jbyte contents) { - oop p = bs()->write_barrier(this); - *p->byte_field_addr(offset) = (jint) contents; -} +inline jbyte oopDesc::byte_field(int offset) const { return (jbyte) *byte_field_addr(offset); } +inline void oopDesc::byte_field_put(int offset, jbyte contents) { *byte_field_addr(offset) = (jint) contents; } -inline jboolean oopDesc::bool_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (jboolean) *p->bool_field_addr(offset); -} -inline void oopDesc::bool_field_put(int offset, jboolean contents) { - oop p = bs()->write_barrier(this); - *p->bool_field_addr(offset) = (( (jint) contents) & 1); -} +inline jboolean oopDesc::bool_field(int offset) const { return (jboolean) *bool_field_addr(offset); } +inline void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (( (jint) contents) & 1); } -inline jchar oopDesc::char_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (jchar) *p->char_field_addr(offset); -} -inline void oopDesc::char_field_put(int offset, jchar contents) { - oop p = bs()->write_barrier(this); - *p->char_field_addr(offset) = (jint) contents; -} +inline jchar oopDesc::char_field(int offset) const { return (jchar) *char_field_addr(offset); } +inline void oopDesc::char_field_put(int offset, jchar contents) { *char_field_addr(offset) = (jint) contents; } -inline jint oopDesc::int_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->int_field_addr(offset); -} -inline void oopDesc::int_field_put(int offset, jint contents) { - oop p = bs()->write_barrier(this); - *p->int_field_addr(offset) = contents; -} -inline void oopDesc::int_field_put_raw(int offset, jint contents) { - *int_field_addr(offset) = contents; -} +inline jint oopDesc::int_field(int offset) const { return *int_field_addr(offset); } +inline void oopDesc::int_field_put(int offset, jint contents) { *int_field_addr(offset) = contents; } -inline jshort oopDesc::short_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (jshort) *p->short_field_addr(offset); -} -inline void oopDesc::short_field_put(int offset, jshort contents) { - oop p = bs()->write_barrier(this); - *p->short_field_addr(offset) = (jint) contents; -} +inline jshort oopDesc::short_field(int offset) const { return (jshort) *short_field_addr(offset); } +inline void oopDesc::short_field_put(int offset, jshort contents) { *short_field_addr(offset) = (jint) contents;} -inline jlong oopDesc::long_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->long_field_addr(offset); -} -inline void oopDesc::long_field_put(int offset, jlong contents) { - oop p = bs()->write_barrier(this); - *p->long_field_addr(offset) = contents; -} +inline jlong oopDesc::long_field(int offset) const { return *long_field_addr(offset); } +inline void oopDesc::long_field_put(int offset, jlong contents) { *long_field_addr(offset) = contents; } -inline jfloat oopDesc::float_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->float_field_addr(offset); -} -inline void oopDesc::float_field_put(int offset, jfloat contents) { - oop p = bs()->write_barrier(this); - *p->float_field_addr(offset) = contents; -} +inline jfloat oopDesc::float_field(int offset) const { return *float_field_addr(offset); } +inline void oopDesc::float_field_put(int offset, jfloat contents) { *float_field_addr(offset) = contents; } -inline jdouble oopDesc::double_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->double_field_addr(offset); -} -inline void oopDesc::double_field_put(int offset, jdouble contents) { - oop p = bs()->write_barrier(this); - *p->double_field_addr(offset) = contents; -} +inline jdouble oopDesc::double_field(int offset) const { return *double_field_addr(offset); } +inline void oopDesc::double_field_put(int offset, jdouble contents) { *double_field_addr(offset) = contents; } -inline address oopDesc::address_field(int offset) const { - oop p = bs()->read_barrier((oop) this); - return *p->address_field_addr(offset); -} -inline void oopDesc::address_field_put(int offset, address contents) { - oop p = bs()->write_barrier(this); - *p->address_field_addr(offset) = contents; -} +inline address oopDesc::address_field(int offset) const { return *address_field_addr(offset); } +inline void oopDesc::address_field_put(int offset, address contents) { *address_field_addr(offset) = contents; } inline oop oopDesc::obj_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return UseCompressedOops ? + oop obj = UseCompressedOops ? decode_heap_oop((narrowOop) - OrderAccess::load_acquire(p->obj_field_addr(offset))) + OrderAccess::load_acquire(obj_field_addr(offset))) : decode_heap_oop((oop) - OrderAccess::load_ptr_acquire(p->obj_field_addr(offset))); + OrderAccess::load_ptr_acquire(obj_field_addr(offset))); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + obj = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(obj); + } +#endif + return obj; } inline void oopDesc::release_obj_field_put(int offset, oop value) { - oop p = bs()->write_barrier(this); - value = bs()->read_barrier(value); UseCompressedOops ? - oop_store((volatile narrowOop*)p->obj_field_addr(offset), value) : - oop_store((volatile oop*) p->obj_field_addr(offset), value); + oop_store((volatile narrowOop*)obj_field_addr(offset), value) : + oop_store((volatile oop*) obj_field_addr(offset), value); } -inline jbyte oopDesc::byte_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->byte_field_addr(offset)); -} -inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->byte_field_addr(offset), contents); -} +inline jbyte oopDesc::byte_field_acquire(int offset) const { return OrderAccess::load_acquire(byte_field_addr(offset)); } +inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { OrderAccess::release_store(byte_field_addr(offset), contents); } -inline jboolean oopDesc::bool_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->bool_field_addr(offset)); -} -inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->bool_field_addr(offset), (contents & 1)); -} +inline jboolean oopDesc::bool_field_acquire(int offset) const { return OrderAccess::load_acquire(bool_field_addr(offset)); } +inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); } -inline jchar oopDesc::char_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->char_field_addr(offset)); -} -inline void oopDesc::release_char_field_put(int offset, jchar contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->char_field_addr(offset), contents); -} +inline jchar oopDesc::char_field_acquire(int offset) const { return OrderAccess::load_acquire(char_field_addr(offset)); } +inline void oopDesc::release_char_field_put(int offset, jchar contents) { OrderAccess::release_store(char_field_addr(offset), contents); } -inline jint oopDesc::int_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->int_field_addr(offset)); -} -inline void oopDesc::release_int_field_put(int offset, jint contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->int_field_addr(offset), contents); -} +inline jint oopDesc::int_field_acquire(int offset) const { return OrderAccess::load_acquire(int_field_addr(offset)); } +inline void oopDesc::release_int_field_put(int offset, jint contents) { OrderAccess::release_store(int_field_addr(offset), contents); } -inline jshort oopDesc::short_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset)); -} -inline void oopDesc::release_short_field_put(int offset, jshort contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->short_field_addr(offset), contents); -} +inline jshort oopDesc::short_field_acquire(int offset) const { return (jshort)OrderAccess::load_acquire(short_field_addr(offset)); } +inline void oopDesc::release_short_field_put(int offset, jshort contents) { OrderAccess::release_store(short_field_addr(offset), contents); } -inline jlong oopDesc::long_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->long_field_addr(offset)); -} -inline void oopDesc::release_long_field_put(int offset, jlong contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->long_field_addr(offset), contents); -} +inline jlong oopDesc::long_field_acquire(int offset) const { return OrderAccess::load_acquire(long_field_addr(offset)); } +inline void oopDesc::release_long_field_put(int offset, jlong contents) { OrderAccess::release_store(long_field_addr(offset), contents); } -inline jfloat oopDesc::float_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->float_field_addr(offset)); -} -inline void oopDesc::release_float_field_put(int offset, jfloat contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->float_field_addr(offset), contents); -} +inline jfloat oopDesc::float_field_acquire(int offset) const { return OrderAccess::load_acquire(float_field_addr(offset)); } +inline void oopDesc::release_float_field_put(int offset, jfloat contents) { OrderAccess::release_store(float_field_addr(offset), contents); } -inline jdouble oopDesc::double_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return OrderAccess::load_acquire(p->double_field_addr(offset)); -} -inline void oopDesc::release_double_field_put(int offset, jdouble contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store(p->double_field_addr(offset), contents); -} +inline jdouble oopDesc::double_field_acquire(int offset) const { return OrderAccess::load_acquire(double_field_addr(offset)); } +inline void oopDesc::release_double_field_put(int offset, jdouble contents) { OrderAccess::release_store(double_field_addr(offset), contents); } -inline address oopDesc::address_field_acquire(int offset) const { - oop p = bs()->read_barrier((oop) this); - return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset)); -} -inline void oopDesc::release_address_field_put(int offset, address contents) { - oop p = bs()->write_barrier(this); - OrderAccess::release_store_ptr(p->address_field_addr(offset), contents); -} +inline address oopDesc::address_field_acquire(int offset) const { return (address) OrderAccess::load_ptr_acquire(address_field_addr(offset)); } +inline void oopDesc::release_address_field_put(int offset, address contents) { OrderAccess::release_store_ptr(address_field_addr(offset), contents); } inline int oopDesc::size_given_klass(Klass* klass) { int lh = klass->layout_helper(); @@ -666,6 +569,11 @@ volatile HeapWord *dest, oop compare_value, bool prebarrier) { +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && ShenandoahCASBarrier) { + return ShenandoahBarrierSet::barrier_set()->oop_atomic_cmpxchg_in_heap(exchange_value, dest, compare_value); + } +#endif if (UseCompressedOops) { if (prebarrier) { update_barrier_set_pre((narrowOop*)dest, exchange_value); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oopsHierarchy.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oopsHierarchy.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/oopsHierarchy.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/oopsHierarchy.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,9 +27,6 @@ #include "runtime/globals.hpp" #include "utilities/globalDefinitions.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/shenandoah/shenandoah_globals.hpp" -#endif // OBJECT hierarchy // This hierarchy is a representation hierarchy, i.e. if A is a superclass @@ -102,23 +99,9 @@ // General access oopDesc* operator->() const { return obj(); } - bool operator==(const oop o) const { -#if INCLUDE_ALL_GCS - if (ShenandoahVerifyObjectEquals) { - ShouldNotReachHere(); - } -#endif - return obj() == o.obj(); - } + bool operator==(const oop o) const { return obj() == o.obj(); } bool operator==(void *p) const { return obj() == p; } - bool operator!=(const volatile oop o) const { -#if INCLUDE_ALL_GCS - if (ShenandoahVerifyObjectEquals) { - ShouldNotReachHere(); - } -#endif - return obj() != o.obj(); - } + bool operator!=(const volatile oop o) const { return obj() != o.obj(); } bool operator!=(void *p) const { return obj() != p; } bool operator<(oop o) const { return obj() < o.obj(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/typeArrayKlass.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/typeArrayKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/typeArrayKlass.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/typeArrayKlass.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -148,9 +148,6 @@ if (length == 0) return; - s = arrayOop(oopDesc::bs()->read_barrier(s)); - d = arrayOop(oopDesc::bs()->write_barrier(d)); - // This is an attempt to make the copy_array fast. int l2es = log2_element_size(); int ihs = array_header_in_bytes() / wordSize; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/typeArrayOop.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/typeArrayOop.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/oops/typeArrayOop.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/oops/typeArrayOop.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OOPS_TYPEARRAYOOP_HPP #define SHARE_VM_OOPS_TYPEARRAYOOP_HPP -#include "memory/barrierSet.hpp" #include "oops/arrayOop.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/orderAccess.inline.hpp" @@ -50,146 +49,117 @@ public: jbyte* byte_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->byte_base()[which]; + return &byte_base()[which]; } jboolean* bool_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->bool_base()[which]; + return &bool_base()[which]; } jchar* char_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->char_base()[which]; + return &char_base()[which]; } jint* int_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->int_base()[which]; + return &int_base()[which]; } jshort* short_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->short_base()[which]; + return &short_base()[which]; } jushort* ushort_at_addr(int which) const { // for field descriptor arrays assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return (jushort*) &p->short_base()[which]; + return (jushort*) &short_base()[which]; } jlong* long_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->long_base()[which]; + return &long_base()[which]; } jfloat* float_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->float_base()[which]; + return &float_base()[which]; } jdouble* double_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(oop(this))); - return &p->double_base()[which]; + return &double_base()[which]; } jbyte byte_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->byte_at_addr(which); + return *byte_at_addr(which); } void byte_at_put(int which, jbyte contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->byte_at_addr(which) = contents; + *byte_at_addr(which) = contents; } jboolean bool_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->bool_at_addr(which); + return *bool_at_addr(which); } void bool_at_put(int which, jboolean contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->bool_at_addr(which) = (((jint)contents) & 1); + *bool_at_addr(which) = (((jint)contents) & 1); } jchar char_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->char_at_addr(which); + return *char_at_addr(which); } void char_at_put(int which, jchar contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->char_at_addr(which) = contents; + *char_at_addr(which) = contents; } jint int_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->int_at_addr(which); + return *int_at_addr(which); } void int_at_put(int which, jint contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->int_at_addr(which) = contents; + *int_at_addr(which) = contents; } jshort short_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->short_at_addr(which); + return *short_at_addr(which); } void short_at_put(int which, jshort contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->short_at_addr(which) = contents; + *short_at_addr(which) = contents; } jushort ushort_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->ushort_at_addr(which); + return *ushort_at_addr(which); } void ushort_at_put(int which, jushort contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->ushort_at_addr(which) = contents; + *ushort_at_addr(which) = contents; } jlong long_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->long_at_addr(which); + return *long_at_addr(which); } void long_at_put(int which, jlong contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->long_at_addr(which) = contents; + *long_at_addr(which) = contents; } jfloat float_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->float_at_addr(which); + return *float_at_addr(which); } void float_at_put(int which, jfloat contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->float_at_addr(which) = contents; + *float_at_addr(which) = contents; } jdouble double_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return *p->double_at_addr(which); + return *double_at_addr(which); } void double_at_put(int which, jdouble contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->double_at_addr(which) = contents; + *double_at_addr(which) = contents; } jbyte byte_at_acquire(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return OrderAccess::load_acquire(p->byte_at_addr(which)); + return OrderAccess::load_acquire(byte_at_addr(which)); } void release_byte_at_put(int which, jbyte contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - OrderAccess::release_store(p->byte_at_addr(which), contents); + OrderAccess::release_store(byte_at_addr(which), contents); } // Java thinks metadata arrays are just arrays of either long or int, since @@ -197,21 +167,17 @@ // casting #ifdef _LP64 Metadata* metadata_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return (Metadata*)*p->long_at_addr(which); + return (Metadata*)*long_at_addr(which); } void metadata_at_put(int which, Metadata* contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->long_at_addr(which) = (jlong)contents; + *long_at_addr(which) = (jlong)contents; } #else Metadata* metadata_at(int which) const { - typeArrayOop p = typeArrayOop(oopDesc::bs()->read_barrier((oop) this)); - return (Metadata*)*p->int_at_addr(which); + return (Metadata*)*int_at_addr(which); } void metadata_at_put(int which, Metadata* contents) { - typeArrayOop p = typeArrayOop(oopDesc::bs()->write_barrier(this)); - *p->int_at_addr(which) = (int)contents; + *int_at_addr(which) = (int)contents; } #endif // _LP64 diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/addnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/addnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/addnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/addnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -30,8 +30,10 @@ #include "opto/machnode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -639,38 +641,6 @@ } } - if (UseShenandoahGC && - in(Base) == in(AddPNode::Address) && - phase->type(in(Base)) == TypePtr::NULL_PTR) { - if (can_reshape) { - for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { - Node* u = fast_out(i); - if (u->is_LoadStore()) { - if (u->as_LoadStore()->adr_type() != NULL) { - u->as_LoadStore()->set_adr_type(TypeRawPtr::BOTTOM); - } - } -#ifdef ASSERT - else if (u->is_Mem()) { - assert(u->as_Mem()->raw_adr_type() == TypeOopPtr::BOTTOM, "bad slice"); - u->as_Mem()->set_raw_adr_type(TypeRawPtr::BOTTOM); - } else if (u->Opcode() == Op_CallLeafNoFP && !strcmp(u->as_CallLeaf()->_name, "unsafe_arraycopy")) { - assert(u->in(0) == NULL || u->in(0)->is_top() || u->in(0)->in(0) == NULL || u->in(0)->in(0)->is_top() || - (u->in(0)->is_Proj() && u->in(0)->in(0)->is_MemBar()), "need membar before"); - Node* c = u->unique_ctrl_out(); - assert(c == NULL || c->is_Proj(), "need membar after"); - c = c->unique_ctrl_out(); - assert(c == NULL || c->is_MemBar(), "need membar after"); - } else { - u->dump(); - ShouldNotReachHere(); - } -#endif - } - } - return new (phase->C) CastX2PNode(in(AddPNode::Offset)); - } - return NULL; // No progress } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/callnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/callnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/callnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/callnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,7 +37,9 @@ #include "opto/regmask.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -1553,8 +1555,14 @@ Node *n = ctrl_proj->in(0); if (n != NULL && n->is_Unlock()) { UnlockNode *unlock = n->as_Unlock(); - Node* lock_obj = ShenandoahBarrierNode::skip_through_barrier(lock->obj_node()); - Node* unlock_obj = ShenandoahBarrierNode::skip_through_barrier(unlock->obj_node()); + Node* lock_obj = lock->obj_node(); + Node* unlock_obj = unlock->obj_node(); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj); + unlock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(unlock_obj); + } +#endif if (lock_obj->eqv_uncast(unlock_obj) && BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) && !unlock->is_eliminated()) { @@ -1600,8 +1608,14 @@ } if (ctrl->is_Lock()) { LockNode *lock = ctrl->as_Lock(); - Node* lock_obj = ShenandoahBarrierNode::skip_through_barrier(lock->obj_node()); - Node* unlock_obj = ShenandoahBarrierNode::skip_through_barrier(unlock->obj_node()); + Node* lock_obj = lock->obj_node(); + Node* unlock_obj = unlock->obj_node(); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj); + unlock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(unlock_obj); + } +#endif if (lock_obj->eqv_uncast(unlock_obj) && BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) { lock_result = lock; @@ -1633,8 +1647,14 @@ } if (lock1_node != NULL && lock1_node->is_Lock()) { LockNode *lock1 = lock1_node->as_Lock(); - Node* lock_obj = ShenandoahBarrierNode::skip_through_barrier(lock->obj_node()); - Node* lock1_obj = ShenandoahBarrierNode::skip_through_barrier(lock1->obj_node()); + Node* lock_obj = lock->obj_node(); + Node* lock1_obj = lock1->obj_node(); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj); + lock1_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock1_obj); + } +#endif if (lock_obj->eqv_uncast(lock1_obj) && BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) && !lock1->is_eliminated()) { @@ -1831,7 +1851,11 @@ return false; } - obj = ShenandoahBarrierNode::skip_through_barrier(obj); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(obj); + } +#endif // Look for external lock for the same object. SafePointNode* sfn = this->as_SafePoint(); JVMState* youngest_jvms = sfn->jvms(); @@ -1842,7 +1866,11 @@ // Loop over monitors for (int idx = 0; idx < num_mon; idx++) { Node* obj_node = sfn->monitor_obj(jvms, idx); - obj_node = ShenandoahBarrierNode::skip_through_barrier(obj_node); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + obj_node = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(obj_node); + } +#endif BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock(); if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) { return true; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/cfgnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/cfgnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/cfgnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/cfgnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -35,8 +35,11 @@ #include "opto/phaseX.hpp" #include "opto/regmask.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -1266,7 +1269,13 @@ } else return NULL; // Build int->bool conversion - Node *n = new (phase->C) Conv2BNode(ShenandoahBarrierNode::skip_through_barrier(cmp->in(1))); + Node* in1 = cmp->in(1); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + in1 = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(in1); + } +#endif + Node *n = new (phase->C) Conv2BNode(in1); if( flipped ) n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/classes.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/classes.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/classes.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/classes.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,9 +37,11 @@ #include "opto/multnode.hpp" #include "opto/node.hpp" #include "opto/rootnode.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" #include "opto/vectornode.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // ---------------------------------------------------------------------------- // Build a table of virtual functions to map from Nodes to dense integer diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/classes.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/classes.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/classes.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/classes.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -230,9 +230,9 @@ macro(RoundFloat) macro(SafePoint) macro(SafePointScalarObject) -macro(ShenandoahReadBarrier) -macro(ShenandoahWriteBarrier) -macro(ShenandoahWBMemProj) +macro(ShenandoahCompareAndSwapN) +macro(ShenandoahCompareAndSwapP) +macro(ShenandoahLoadReferenceBarrier) macro(SCMemProj) macro(SinD) macro(SqrtD) diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/compile.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/compile.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/compile.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/compile.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,7 +32,6 @@ #include "compiler/compileLog.hpp" #include "compiler/disassembler.hpp" #include "compiler/oopMap.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "opto/addnode.hpp" #include "opto/block.hpp" #include "opto/c2compiler.hpp" @@ -59,7 +58,6 @@ #include "opto/phaseX.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/stringopts.hpp" #include "opto/type.hpp" #include "opto/vectornode.hpp" @@ -85,6 +83,11 @@ # include "adfiles/ad_ppc_64.hpp" #endif +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif + // -------------------- Compile::mach_constant_base_node ----------------------- // Constant table base node singleton. MachConstantBaseNode* Compile::mach_constant_base_node() { @@ -435,9 +438,9 @@ } } for (int i = C->shenandoah_barriers_count()-1; i >= 0; i--) { - Node* n = C->shenandoah_barrier(i); + ShenandoahLoadReferenceBarrierNode* n = C->shenandoah_barrier(i); if (!useful.member(n)) { - remove_shenandoah_barrier(n->as_ShenandoahBarrier()); + remove_shenandoah_barrier(n); } } // clean up the late inline lists @@ -1176,7 +1179,7 @@ _predicate_opaqs = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL); _expensive_nodes = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL); _range_check_casts = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL); - _shenandoah_barriers = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL); + _shenandoah_barriers = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL); register_library_intrinsics(); } @@ -1421,9 +1424,6 @@ tj = TypeInstPtr::MARK; ta = TypeAryPtr::RANGE; // generic ignored junk ptr = TypePtr::BotPTR; - } else if (offset == ShenandoahBrooksPointer::byte_offset() && UseShenandoahGC) { - // Need to distinguish brooks ptr as is. - tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); } else { // Random constant offset into array body offset = Type::OffsetBot; // Flatten constant access into array body tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); @@ -1488,7 +1488,7 @@ if (!is_known_inst) { // Do it only for non-instance types tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); } - } else if ((offset != ShenandoahBrooksPointer::byte_offset() || !UseShenandoahGC) && (offset < 0 || offset >= k->size_helper() * wordSize)) { + } else if (offset < 0 || offset >= k->size_helper() * wordSize) { // Static fields are in the space above the normal instance // fields in the java.lang.Class instance. if (to->klass() != ciEnv::current()->Class_klass()) { @@ -1586,8 +1586,7 @@ (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) || (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) || (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) || - (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) || - (offset == ShenandoahBrooksPointer::byte_offset() && tj->base() == Type::AryPtr && UseShenandoahGC), + (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) , "For oops, klasses, raw offset must be constant; for arrays the offset is never known" ); assert( tj->ptr() != TypePtr::TopPTR && tj->ptr() != TypePtr::AnyNull && @@ -2293,7 +2292,7 @@ #ifdef ASSERT if (UseShenandoahGC && ShenandoahVerifyOptoBarriers) { - ShenandoahBarrierNode::verify(C->root()); + ShenandoahBarrierC2Support::verify(C->root()); } #endif @@ -2306,15 +2305,11 @@ } } +#if INCLUDE_ALL_GCS if (UseShenandoahGC) { - if (shenandoah_barriers_count() > 0) { - C->clear_major_progress(); - PhaseIdealLoop ideal_loop(igvn, false, true); - if (failing()) return; - PhaseIdealLoop::verify(igvn); - DEBUG_ONLY(ShenandoahBarrierNode::verify_raw_mem(C->root());) - } + ShenandoahBarrierC2Support::expand(this, igvn); } +#endif } // (End scope of igvn; run destructor if necessary for asserts.) @@ -2916,7 +2911,7 @@ Node *m = wq.at(next); for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { Node* use = m->fast_out(i); - if (use->is_Mem() || use->is_EncodeNarrowPtr() || use->is_ShenandoahBarrier()) { + if (use->is_Mem() || use->is_EncodeNarrowPtr() || use->Opcode() == Op_ShenandoahLoadReferenceBarrier) { use->ensure_control_or_add_prec(n->in(0)); } else if (use->in(0) == NULL) { switch(use->Opcode()) { @@ -3240,9 +3235,7 @@ n->set_req(MemBarNode::Precedent, top()); } break; - case Op_ShenandoahReadBarrier: - break; - case Op_ShenandoahWriteBarrier: + case Op_ShenandoahLoadReferenceBarrier: assert(false, "should have been expanded already"); break; default: diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/compile.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/compile.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/compile.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/compile.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -69,7 +69,7 @@ class PhaseCCP_DCE; class RootNode; class relocInfo; -class ShenandoahBarrierNode; +class ShenandoahLoadReferenceBarrierNode; class Scope; class StartNode; class SafePointNode; @@ -339,7 +339,7 @@ GrowableArray* _predicate_opaqs; // List of Opaque1 nodes for the loop predicates. GrowableArray* _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common GrowableArray* _range_check_casts; // List of CastII nodes with a range check dependency - GrowableArray* _shenandoah_barriers; + GrowableArray* _shenandoah_barriers; ConnectionGraph* _congraph; #ifndef PRODUCT IdealGraphPrinter* _printer; @@ -673,7 +673,7 @@ Node* macro_node(int idx) const { return _macro_nodes->at(idx); } Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);} Node* expensive_node(int idx) const { return _expensive_nodes->at(idx); } - ShenandoahBarrierNode* shenandoah_barrier(int idx) const { return _shenandoah_barriers->at(idx); } + ShenandoahLoadReferenceBarrierNode* shenandoah_barrier(int idx) const { return _shenandoah_barriers->at(idx); } ConnectionGraph* congraph() { return _congraph;} void set_congraph(ConnectionGraph* congraph) { _congraph = congraph;} void add_macro_node(Node * n) { @@ -697,11 +697,11 @@ _expensive_nodes->remove(n); } } - void add_shenandoah_barrier(ShenandoahBarrierNode * n) { + void add_shenandoah_barrier(ShenandoahLoadReferenceBarrierNode * n) { assert(!_shenandoah_barriers->contains(n), "duplicate entry in barrier list"); _shenandoah_barriers->append(n); } - void remove_shenandoah_barrier(ShenandoahBarrierNode * n) { + void remove_shenandoah_barrier(ShenandoahLoadReferenceBarrierNode * n) { if (_shenandoah_barriers->contains(n)) { _shenandoah_barriers->remove(n); } @@ -738,7 +738,7 @@ // Sort expensive nodes to locate similar expensive nodes void sort_expensive_nodes(); - GrowableArray* shenandoah_barriers() { return _shenandoah_barriers; } + GrowableArray* shenandoah_barriers() { return _shenandoah_barriers; } // Compilation environment. Arena* comp_arena() { return &_comp_arena; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/escape.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/escape.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/escape.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/escape.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,7 +34,9 @@ #include "opto/escape.hpp" #include "opto/phaseX.hpp" #include "opto/rootnode.hpp" -#include "opto/shenandoahSupport.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) : _nodes(C->comp_arena(), C->unique(), C->unique(), NULL), @@ -566,12 +568,11 @@ add_java_object(n, PointsToNode::ArgEscape); break; } - case Op_ShenandoahReadBarrier: - case Op_ShenandoahWriteBarrier: - // Barriers 'pass through' its arguments. I.e. what goes in, comes out. - // It doesn't escape. - add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), delayed_worklist); +#if INCLUDE_ALL_GCS + case Op_ShenandoahLoadReferenceBarrier: + add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), delayed_worklist); break; +#endif default: ; // Do nothing for nodes not related to EA. } @@ -766,13 +767,12 @@ } break; } - case Op_ShenandoahReadBarrier: - case Op_ShenandoahWriteBarrier: - // Barriers 'pass through' its arguments. I.e. what goes in, comes out. - // It doesn't escape. - add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), NULL); +#if INCLUDE_ALL_GCS + case Op_ShenandoahLoadReferenceBarrier: + add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), NULL); break; - default: { +#endif + default: { // This method should be called only for EA specific nodes which may // miss some edges when they were created. #ifdef ASSERT @@ -967,6 +967,7 @@ strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || + strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 || @@ -2129,6 +2130,9 @@ return false; } PointsToNode* ptn = ptnode_adr(idx); + if (ptn == NULL) { + return false; // not in congraph (e.g. ConI) + } PointsToNode::EscapeState es = ptn->escape_state(); // If we have already computed a value, return it. if (es >= PointsToNode::GlobalEscape) @@ -2289,7 +2293,7 @@ (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) || (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()) || (uncast_base->is_Phi() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) || - uncast_base->is_ShenandoahBarrier(), "sanity"); + uncast_base->Opcode() == Op_ShenandoahLoadReferenceBarrier, "sanity"); } return base; } @@ -2991,7 +2995,6 @@ n->is_CheckCastPP() || n->is_EncodeP() || n->is_DecodeN() || - n->is_ShenandoahBarrier() || (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { if (visited.test_set(n->_idx)) { assert(n->is_Phi(), "loops only through Phi's"); @@ -3062,7 +3065,6 @@ use->is_CheckCastPP() || use->is_EncodeNarrowPtr() || use->is_DecodeNarrowPtr() || - use->is_ShenandoahBarrier() || (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { alloc_worklist.append_if_missing(use); #ifdef ASSERT @@ -3087,8 +3089,7 @@ if (!(op == Op_CmpP || op == Op_Conv2B || op == Op_CastP2X || op == Op_StoreCM || op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || - op == Op_StrEquals || op == Op_StrIndexOf || - op == Op_ShenandoahWBMemProj)) { + op == Op_StrEquals || op == Op_StrIndexOf)) { n->dump(); use->dump(); assert(false, "EA: missing allocation reference path"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/graphKit.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/graphKit.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/graphKit.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/graphKit.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,7 +27,6 @@ #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" #include "gc_interface/collectedHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.hpp" #include "memory/barrierSet.hpp" #include "memory/cardTableModRefBS.hpp" @@ -39,10 +38,14 @@ #include "opto/parse.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "runtime/deoptimization.hpp" #include "runtime/sharedRuntime.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif + //----------------------------GraphKit----------------------------------------- // Main utility constructor. GraphKit::GraphKit(JVMState* jvms) @@ -592,8 +595,6 @@ const TypeInstPtr* ex_con = TypeInstPtr::make(ex_obj); Node* ex_node = _gvn.transform( ConNode::make(C, ex_con) ); - ex_node = shenandoah_write_barrier(ex_node); - // Clear the detail message of the preallocated exception object. // Weblogic sometimes mutates the detail message of exceptions // using reflection. @@ -1538,10 +1539,13 @@ switch (bs->kind()) { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: - case BarrierSet::ShenandoahBarrierSet: g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt); break; - + case BarrierSet::ShenandoahBarrierSet: + if (ShenandoahSATBBarrier) { + g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt); + } + break; case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: case BarrierSet::ModRef: @@ -1589,14 +1593,17 @@ case BarrierSet::G1SATBCTLogging: g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise); break; - + case BarrierSet::ShenandoahBarrierSet: + if (ShenandoahStoreValEnqueueBarrier) { + g1_write_barrier_pre(false, NULL, NULL, max_juint, NULL, NULL, val, bt); + } + break; case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: write_barrier_post(store, obj, adr, adr_idx, val, use_precise); break; case BarrierSet::ModRef: - case BarrierSet::ShenandoahBarrierSet: break; case BarrierSet::Other: @@ -1714,6 +1721,7 @@ if (elembt == T_NARROWOOP) { elembt = T_OBJECT; // To satisfy switch in LoadNode::make() } + assert(elembt != T_OBJECT && elembt != T_ARRAY, "sanity"); Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered); return ld; } @@ -3176,8 +3184,6 @@ assert(dead_locals_are_killed(), "should kill locals before sync. point"); - obj = shenandoah_write_barrier(obj); - // Box the stack location Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor())); Node* mem = reset_memory(); @@ -3676,9 +3682,11 @@ return NULL; } - // Attempt to see through Shenandoah barriers. - ptr = ShenandoahBarrierNode::skip_through_barrier(ptr); - +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + ptr = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(ptr); + } +#endif if (ptr->is_CheckCastPP()) { // strip only one raw-to-oop cast ptr = ptr->in(1); if (ptr == NULL) return NULL; @@ -3946,8 +3954,8 @@ if (UseShenandoahGC) { Node* gc_state = __ AddP(no_base, tls, __ ConX(in_bytes(JavaThread::gc_state_offset()))); Node* ld = __ load(__ ctrl(), gc_state, TypeInt::BYTE, T_BYTE, Compile::AliasIdxRaw); - marking = __ AndI(ld, __ ConI(ShenandoahHeap::MARKING)); - assert(ShenandoahWriteBarrierNode::is_gc_state_load(ld), "Should match the shape"); + marking = __ AndI(ld, __ ConI(ShenandoahHeap::MARKING | ShenandoahHeap::TRAVERSAL)); + assert(ShenandoahBarrierC2Support::is_gc_state_load(ld), "Should match the shape"); } else { assert(UseG1GC, "should be"); marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); @@ -4165,11 +4173,6 @@ false, NULL, 0); const TypePtr* count_field_type = string_type->add_offset(count_offset); int count_field_idx = C->get_alias_index(count_field_type); - - if (! ShenandoahOptimizeInstanceFinals) { - str = shenandoah_read_barrier(str); - } - return make_load(ctrl, basic_plus_adr(str, str, count_offset), TypeInt::INT, T_INT, count_field_idx, MemNode::unordered); @@ -4187,13 +4190,13 @@ TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); int value_field_idx = C->get_alias_index(value_field_type); - - if (!ShenandoahOptimizeInstanceFinals) { - str = shenandoah_read_barrier(str); - } - Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset), value_type, T_OBJECT, value_field_idx, MemNode::unordered); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + load = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, load); + } +#endif // String.value field is known to be @Stable. if (UseImplicitStableValues) { load = cast_array_to_stable(load, value_type); @@ -4207,9 +4210,6 @@ false, NULL, 0); const TypePtr* offset_field_type = string_type->add_offset(offset_offset); int offset_field_idx = C->get_alias_index(offset_field_type); - - str = shenandoah_write_barrier(str); - store_to_memory(ctrl, basic_plus_adr(str, offset_offset), value, T_INT, offset_field_idx, MemNode::unordered); } @@ -4220,9 +4220,6 @@ false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - value = shenandoah_read_barrier_storeval(value); - str = shenandoah_write_barrier(str); - store_oop_to_object(ctrl, str, basic_plus_adr(str, value_offset), value_field_type, value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered); } @@ -4233,9 +4230,6 @@ false, NULL, 0); const TypePtr* count_field_type = string_type->add_offset(count_offset); int count_field_idx = C->get_alias_index(count_field_type); - - str = shenandoah_write_barrier(str); - store_to_memory(ctrl, basic_plus_adr(str, count_offset), value, T_INT, count_field_idx, MemNode::unordered); } @@ -4245,125 +4239,3 @@ // assumption of CCP analysis. return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true))); } - -Node* GraphKit::shenandoah_read_barrier(Node* obj) { - return shenandoah_read_barrier_impl(obj, false, true, true); -} - -Node* GraphKit::shenandoah_read_barrier_storeval(Node* obj) { - return shenandoah_read_barrier_impl(obj, true, false, false); -} - -Node* GraphKit::shenandoah_read_barrier_impl(Node* obj, bool use_ctrl, bool use_mem, bool allow_fromspace) { - - if (UseShenandoahGC && ShenandoahReadBarrier) { - const Type* obj_type = obj->bottom_type(); - if (obj_type->higher_equal(TypePtr::NULL_PTR)) { - return obj; - } - const TypePtr* adr_type = ShenandoahBarrierNode::brooks_pointer_type(obj_type); - Node* mem = use_mem ? memory(adr_type) : immutable_memory(); - - if (! ShenandoahBarrierNode::needs_barrier(&_gvn, NULL, obj, mem, allow_fromspace)) { - // We know it is null, no barrier needed. - return obj; - } - - - if (obj_type->meet(TypePtr::NULL_PTR) == obj_type->remove_speculative()) { - - // We don't know if it's null or not. Need null-check. - enum { _not_null_path = 1, _null_path, PATH_LIMIT }; - RegionNode* region = new (C) RegionNode(PATH_LIMIT); - Node* phi = new (C) PhiNode(region, obj_type); - Node* null_ctrl = top(); - Node* not_null_obj = null_check_oop(obj, &null_ctrl); - - region->init_req(_null_path, null_ctrl); - phi ->init_req(_null_path, zerocon(T_OBJECT)); - - Node* ctrl = use_ctrl ? control() : NULL; - ShenandoahReadBarrierNode* rb = new (C) ShenandoahReadBarrierNode(ctrl, mem, not_null_obj, allow_fromspace); - Node* n = _gvn.transform(rb); - - region->init_req(_not_null_path, control()); - phi ->init_req(_not_null_path, n); - - set_control(_gvn.transform(region)); - record_for_igvn(region); - return _gvn.transform(phi); - - } else { - // We know it is not null. Simple barrier is sufficient. - Node* ctrl = use_ctrl ? control() : NULL; - ShenandoahReadBarrierNode* rb = new (C) ShenandoahReadBarrierNode(ctrl, mem, obj, allow_fromspace); - Node* n = _gvn.transform(rb); - record_for_igvn(n); - return n; - } - - } else { - return obj; - } -} - -static Node* shenandoah_write_barrier_helper(GraphKit& kit, Node* obj, const TypePtr* adr_type) { - ShenandoahWriteBarrierNode* wb = new (kit.C) ShenandoahWriteBarrierNode(kit.C, kit.control(), kit.memory(adr_type), obj); - Node* n = kit.gvn().transform(wb); - if (n == wb) { // New barrier needs memory projection. - Node* proj = kit.gvn().transform(new (kit.C) ShenandoahWBMemProjNode(n)); - kit.set_memory(proj, adr_type); - } - - return n; -} - -Node* GraphKit::shenandoah_write_barrier(Node* obj) { - - if (UseShenandoahGC && ShenandoahWriteBarrier) { - - if (! ShenandoahBarrierNode::needs_barrier(&_gvn, NULL, obj, NULL, true)) { - return obj; - } - const Type* obj_type = obj->bottom_type(); - const TypePtr* adr_type = ShenandoahBarrierNode::brooks_pointer_type(obj_type); - if (obj_type->meet(TypePtr::NULL_PTR) == obj_type->remove_speculative()) { - // We don't know if it's null or not. Need null-check. - enum { _not_null_path = 1, _null_path, PATH_LIMIT }; - RegionNode* region = new (C) RegionNode(PATH_LIMIT); - Node* phi = new (C) PhiNode(region, obj_type); - Node* memphi = PhiNode::make(region, memory(adr_type), Type::MEMORY, C->alias_type(adr_type)->adr_type()); - - Node* prev_mem = memory(adr_type); - Node* null_ctrl = top(); - Node* not_null_obj = null_check_oop(obj, &null_ctrl); - - region->init_req(_null_path, null_ctrl); - phi ->init_req(_null_path, zerocon(T_OBJECT)); - memphi->init_req(_null_path, prev_mem); - - Node* n = shenandoah_write_barrier_helper(*this, not_null_obj, adr_type); - - region->init_req(_not_null_path, control()); - phi ->init_req(_not_null_path, n); - memphi->init_req(_not_null_path, memory(adr_type)); - - set_control(_gvn.transform(region)); - record_for_igvn(region); - set_memory(_gvn.transform(memphi), adr_type); - - Node* res_val = _gvn.transform(phi); - // replace_in_map(obj, res_val); - return res_val; - } else { - // We know it is not null. Simple barrier is sufficient. - Node* n = shenandoah_write_barrier_helper(*this, obj, adr_type); - // replace_in_map(obj, n); - record_for_igvn(n); - return n; - } - - } else { - return obj; - } -} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/graphKit.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/graphKit.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/graphKit.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/graphKit.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -915,12 +915,6 @@ // Produce new array node of stable type Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type); - - Node* shenandoah_read_barrier(Node* obj); - Node* shenandoah_read_barrier_storeval(Node* obj); - Node* shenandoah_write_barrier(Node* obj); -private: - Node* shenandoah_read_barrier_impl(Node* obj, bool use_ctrl, bool use_mem, bool allow_fromspace); }; // Helper class to support building of control flow branches. Upon diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/ifnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/ifnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/ifnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/ifnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -626,7 +626,7 @@ cmpx->is_Cmp() && cmpx->in(2) == phase->intcon(0) && cmpx->in(1)->in(1)->is_shenandoah_state_load() && cmpx->in(1)->in(2)->is_Con() && - cmpx->in(1)->in(2) == phase->intcon(ShenandoahHeap::MARKING)) { + cmpx->in(1)->in(2) == phase->intcon(ShenandoahHeap::MARKING | ShenandoahHeap::TRAVERSAL)) { return true; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/lcm.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/lcm.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/lcm.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/lcm.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -187,9 +187,6 @@ case Op_LoadRange: case Op_LoadD_unaligned: case Op_LoadL_unaligned: - case Op_ShenandoahReadBarrier: - assert(mach->in(2) == val, "should be address"); - break; case Op_StoreB: case Op_StoreC: case Op_StoreCM: @@ -637,12 +634,9 @@ //------------------------------add_call_kills------------------------------------- // helper function that adds caller save registers to MachProjNode -static void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe, bool exclude_fp) { +static void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) { // Fill in the kill mask for the call for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { - if (exclude_fp && (register_save_type[r] == Op_RegF || register_save_type[r] == Op_RegD)) { - continue; - } if( !regs.Member(r) ) { // Not already defined by the call // Save-on-call register? if ((save_policy[r] == 'C') || @@ -743,12 +737,7 @@ proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask()); } - if (UseShenandoahGC && mcall->entry_point() == StubRoutines::shenandoah_wb_C()) { - assert(op == Op_CallLeafNoFP, "shenandoah_wb_C should be called with Op_CallLeafNoFP"); - add_call_kills(proj, regs, save_policy, exclude_soe, true); - } else { - add_call_kills(proj, regs, save_policy, exclude_soe, false); - } + add_call_kills(proj, regs, save_policy, exclude_soe); return node_cnt; } @@ -937,7 +926,7 @@ map_node_to_block(proj, block); block->insert_node(proj, phi_cnt++); - add_call_kills(proj, regs, _matcher._c_reg_save_policy, false, false); + add_call_kills(proj, regs, _matcher._c_reg_save_policy, false); } // Children are now all ready diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/library_call.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/library_call.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/library_call.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/library_call.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,12 +37,15 @@ #include "opto/mulnode.hpp" #include "opto/parse.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" #include "prims/nativeLookup.hpp" #include "runtime/sharedRuntime.hpp" #include "trace/traceMacros.hpp" #include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif class LibraryIntrinsic : public InlineCallGenerator { @@ -228,7 +231,7 @@ Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y); // This returns Type::AnyPtr, RawPtr, or OopPtr. int classify_unsafe_addr(Node* &base, Node* &offset); - Node* make_unsafe_address(Node* base, Node* offset, bool is_store); + Node* make_unsafe_address(Node* base, Node* offset); // Helper for inline_unsafe_access. // Generates the guards that check whether the result of // Unsafe.getObject should be recorded in an SATB log buffer. @@ -314,6 +317,7 @@ Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); + bool inline_ghash_processBlocks(); bool inline_sha_implCompress(vmIntrinsics::ID id); bool inline_digestBase_implCompressMB(int predicate); bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, @@ -333,10 +337,6 @@ bool inline_montgomerySquare(); bool inline_profileBoolean(); - - Node* shenandoah_cast_not_null(Node* n) { - return UseShenandoahGC ? cast_not_null(n, false) : n; - } }; @@ -577,6 +577,10 @@ predicates = 3; break; + case vmIntrinsics::_ghash_processBlocks: + if (!UseGHASHIntrinsics) return NULL; + break; + case vmIntrinsics::_updateCRC32: case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: @@ -964,6 +968,9 @@ case vmIntrinsics::_montgomerySquare: return inline_montgomerySquare(); + case vmIntrinsics::_ghash_processBlocks: + return inline_ghash_processBlocks(); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -1169,8 +1176,6 @@ // Get start addr of string Node* str1_value = load_String_value(no_ctrl, str1); - str1_value = shenandoah_cast_not_null(str1_value); - str1_value = shenandoah_read_barrier(str1_value); Node* str1_offset = load_String_offset(no_ctrl, str1); Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR); @@ -1178,8 +1183,6 @@ Node* str1_len = load_String_length(no_ctrl, str1); Node* str2_value = load_String_value(no_ctrl, str2); - str2_value = shenandoah_cast_not_null(str2_value); - str2_value = shenandoah_read_barrier(str2_value); Node* str2_offset = load_String_offset(no_ctrl, str2); Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR); @@ -1273,8 +1276,6 @@ Node* phi = new (C) PhiNode(region, TypeInt::BOOL); // does source == target string? - receiver = shenandoah_write_barrier(receiver); - argument = shenandoah_write_barrier(argument); Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument)); Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq)); @@ -1314,8 +1315,6 @@ // Get start addr of receiver Node* receiver_val = load_String_value(no_ctrl, receiver); - receiver_val = shenandoah_cast_not_null(receiver_val); - receiver_val = shenandoah_read_barrier(receiver_val); Node* receiver_offset = load_String_offset(no_ctrl, receiver); Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR); @@ -1324,8 +1323,6 @@ // Get start addr of argument Node* argument_val = load_String_value(no_ctrl, argument); - argument_val = shenandoah_cast_not_null(argument_val); - argument_val = shenandoah_read_barrier(argument_val); Node* argument_offset = load_String_offset(no_ctrl, argument); Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR); @@ -1362,10 +1359,6 @@ bool LibraryCallKit::inline_array_equals() { Node* arg1 = argument(0); Node* arg2 = argument(1); - - arg1 = shenandoah_read_barrier(arg1); - arg2 = shenandoah_read_barrier(arg2); - set_result(_gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2))); return true; } @@ -1441,8 +1434,6 @@ const int nargs = 0; // no arguments to push back for uncommon trap in predicate Node* source = load_String_value(no_ctrl, string_object); - source = shenandoah_cast_not_null(source); - source = shenandoah_read_barrier(source); Node* sourceOffset = load_String_offset(no_ctrl, string_object); Node* sourceCount = load_String_length(no_ctrl, string_object); @@ -1456,8 +1447,6 @@ target = cast_array_to_stable(target, target_type); } - target = shenandoah_read_barrier(target); - IdealKit kit(this, false, true); #define __ kit. Node* zero = __ ConI(0); @@ -1545,8 +1534,6 @@ // Get start addr of source string Node* source = load_String_value(no_ctrl, receiver); - source = shenandoah_cast_not_null(source); - source = shenandoah_read_barrier(source); Node* source_offset = load_String_offset(no_ctrl, receiver); Node* source_start = array_element_address(source, source_offset, T_CHAR); @@ -1555,8 +1542,6 @@ // Get start addr of substring Node* substr = load_String_value(no_ctrl, arg); - substr = shenandoah_cast_not_null(substr); - substr = shenandoah_read_barrier(substr); Node* substr_offset = load_String_offset(no_ctrl, arg); Node* substr_start = array_element_address(substr, substr_offset, T_CHAR); @@ -1629,7 +1614,6 @@ } receiver = null_check(receiver, T_OBJECT); - receiver = shenandoah_read_barrier(receiver); // NOTE: No null check on the argument is needed since it's a constant String oop. if (stopped()) { return true; @@ -2395,42 +2379,11 @@ } } -inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset, bool is_store) { +inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset) { int kind = classify_unsafe_addr(base, offset); if (kind == Type::RawPtr) { return basic_plus_adr(top(), base, offset); } else { - if (UseShenandoahGC) { - if (kind == Type::OopPtr) { - // A cast without a null check should be sufficient here (we - // know base is an oop with a low offset so it can't be null) - // but if there's a dominating null check with both branches - // taken and the cast is pushed in both branches, the cast - // will become top in the null branch but the control flow - // won't go away. Use a null check instead. Worst case, the - // null check becomes an implicit null check with the follow - // barrier and is essentially free. - Node* ctrl = top(); - base = null_check_oop(base, &ctrl, true); - if (is_store) { - base = shenandoah_write_barrier(base); - } else { - base = shenandoah_read_barrier(base); - } - } else if (kind == Type::AnyPtr) { - if (UseShenandoahGC && - _gvn.type(base)->isa_aryptr()) { - Node* ctrl = top(); - base = null_check_oop(base, &ctrl, true); - } - - if (is_store) { - base = shenandoah_write_barrier(base); - } else { - base = shenandoah_read_barrier(base); - } - } - } return basic_plus_adr(base, offset); } } @@ -2682,13 +2635,13 @@ "fieldOffset must be byte-scaled"); // 32-bit machines ignore the high half! offset = ConvL2X(offset); - adr = make_unsafe_address(base, offset, is_store); + adr = make_unsafe_address(base, offset); heap_base_oop = base; val = is_store ? argument(4) : NULL; } else { Node* ptr = argument(1); // type: long ptr = ConvL2X(ptr); // adjust Java long to machine word - adr = make_unsafe_address(NULL, ptr, is_store); + adr = make_unsafe_address(NULL, ptr); val = is_store ? argument(3) : NULL; } @@ -2806,6 +2759,11 @@ // To be valid, unsafe loads may depend on other conditions than // the one that guards them: pin the Load node load = make_load(control(), adr, value_type, type, adr_type, mo, LoadNode::Pinned, is_volatile, unaligned, mismatched); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (type == T_OBJECT || type == T_ARRAY)) { + load = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, load); + } +#endif // load value switch (type) { case T_BOOLEAN: @@ -2851,7 +2809,6 @@ MemNode::MemOrd mo = is_volatile ? MemNode::release : MemNode::unordered; if (type == T_OBJECT ) { - val = shenandoah_read_barrier_storeval(val); store = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched); } else { store = store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile, unaligned, mismatched); @@ -2860,6 +2817,11 @@ if (is_volatile) { if (!is_store) { +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + load = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(load); + } +#endif Node* mb = insert_mem_bar(Op_MemBarAcquire, load); mb->as_MemBar()->set_trailing_load(); } else { @@ -2922,11 +2884,11 @@ "fieldOffset must be byte-scaled"); // 32-bit machines ignore the high half! offset = ConvL2X(offset); - adr = make_unsafe_address(base, offset, false); + adr = make_unsafe_address(base, offset); } else { Node* ptr = argument(idx + 0); // type: long ptr = ConvL2X(ptr); // adjust Java long to machine word - adr = make_unsafe_address(NULL, ptr, false); + adr = make_unsafe_address(NULL, ptr); } // Generate the read or write prefetch @@ -3029,7 +2991,7 @@ assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); // 32-bit machines ignore the high half of long offsets offset = ConvL2X(offset); - Node* adr = make_unsafe_address(base, offset, true); + Node* adr = make_unsafe_address(base, offset); const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); Compile::AliasType* alias_type = C->alias_type(adr_type); @@ -3106,8 +3068,6 @@ if (_gvn.type(newval) == TypePtr::NULL_PTR) newval = _gvn.makecon(TypePtr::NULL_PTR); - newval = shenandoah_read_barrier_storeval(newval); - // Reference stores need a store barrier. if (kind == LS_xchg) { // If pre-barrier must execute before the oop store, old value will require do_load here. @@ -3174,6 +3134,11 @@ load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); } #endif +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + load_store = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, load_store); + } +#endif if (can_move_pre_barrier()) { // Don't need to load pre_val. The old value is returned by load_store. // The pre_barrier can execute after the xchg as long as no safepoint @@ -3239,7 +3204,7 @@ assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); // 32-bit machines ignore the high half of long offsets offset = ConvL2X(offset); - Node* adr = make_unsafe_address(base, offset, true); + Node* adr = make_unsafe_address(base, offset); const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); const Type *value_type = Type::get_const_basic_type(type); Compile::AliasType* alias_type = C->alias_type(adr_type); @@ -3249,10 +3214,9 @@ // Ensure that the store is atomic for longs: const bool require_atomic_access = true; Node* store; - if (type == T_OBJECT) { // reference stores need a store barrier. - val = shenandoah_read_barrier_storeval(val); + if (type == T_OBJECT) // reference stores need a store barrier. store = store_oop_to_unknown(control(), base, adr, adr_type, val, type, MemNode::release); - } else { + else { store = store_to_memory(control(), adr, val, type, adr_type, MemNode::release, require_atomic_access); } insert_mem_bar(Op_MemBarCPUOrder); @@ -3430,8 +3394,6 @@ Node* rec_thr = argument(0); Node* tls_ptr = NULL; Node* cur_thr = generate_current_thread(tls_ptr); - cur_thr = shenandoah_write_barrier(cur_thr); - rec_thr = shenandoah_write_barrier(rec_thr); Node* cmp_thr = _gvn.transform(new (C) CmpPNode(cur_thr, rec_thr)); Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne)); @@ -3777,9 +3739,7 @@ RegionNode* region = new (C) RegionNode(PATH_LIMIT); Node* phi = new (C) PhiNode(region, TypeInt::BOOL); - Node* mem_phi= new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM); record_for_igvn(region); - Node* init_mem = map()->memory(); const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; @@ -3798,9 +3758,6 @@ klasses[which_arg] = _gvn.transform(kls); } - args[0] = shenandoah_write_barrier(args[0]); - args[1] = shenandoah_write_barrier(args[1]); - // Having loaded both klasses, test each for null. bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); for (which_arg = 0; which_arg <= 1; which_arg++) { @@ -3828,7 +3785,7 @@ set_control(region->in(_prim_0_path)); // go back to first null check if (!stopped()) { // Since superc is primitive, make a guard for the superc==subc case. - Node* cmp_eq = _gvn.transform(new (C)CmpPNode(args[0], args[1])); + Node* cmp_eq = _gvn.transform(new (C) CmpPNode(args[0], args[1])); Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq)); generate_guard(bol_eq, region, PROB_FAIR); if (region->req() == PATH_LIMIT+1) { @@ -3845,24 +3802,18 @@ // pull together the cases: assert(region->req() == PATH_LIMIT, "sane region"); - Node* cur_mem = reset_memory(); for (uint i = 1; i < region->req(); i++) { Node* ctl = region->in(i); if (ctl == NULL || ctl == top()) { region->set_req(i, top()); phi ->set_req(i, top()); - mem_phi->set_req(i, top()); - } else { - if (phi->in(i) == NULL) { + } else if (phi->in(i) == NULL) { phi->set_req(i, intcon(0)); // all other paths produce 'false' } - mem_phi->set_req(i, (i == _prim_0_path || i == _prim_same_path) ? cur_mem : init_mem); - } } set_control(_gvn.transform(region)); set_result(_gvn.transform(phi)); - set_all_memory(_gvn.transform(mem_phi)); return true; } @@ -4077,8 +4028,6 @@ newcopy = new_array(klass_node, length, 0); // no argments to push - original = shenandoah_read_barrier(original); - // Generate a direct call to the right arraycopy function(s). // We know the copy is disjoint but we might not know if the // oop stores need checking. @@ -4526,8 +4475,8 @@ assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); - Node* src = make_unsafe_address(src_ptr, src_off, false); - Node* dst = make_unsafe_address(dst_ptr, dst_off, true); + Node* src = make_unsafe_address(src_ptr, src_off); + Node* dst = make_unsafe_address(dst_ptr, dst_off); // Conservatively insert a memory barrier on all memory slices. // Do not let writes of the copy source or destination float below the copy. @@ -4554,8 +4503,6 @@ Node* raw_obj = alloc_obj->in(1); assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); - obj = shenandoah_read_barrier(obj); - AllocateNode* alloc = NULL; if (ReduceBulkZeroing) { // We will be completely responsible for initializing this object - @@ -4725,9 +4672,6 @@ if (is_obja != NULL) { PreserveJVMState pjvms2(this); set_control(is_obja); - - obj = shenandoah_read_barrier(obj); - // Generate a direct call to the right arraycopy function(s). bool disjoint_bases = true; bool length_never_negative = true; @@ -4945,9 +4889,6 @@ // Do not let writes into the source float below the arraycopy. insert_mem_bar(Op_MemBarCPUOrder); - src = shenandoah_read_barrier(src); - dest = shenandoah_write_barrier(dest); - // Call StubRoutines::generic_arraycopy stub. generate_arraycopy(TypeRawPtr::BOTTOM, T_CONFLICT, src, src_offset, dest, dest_offset, length); @@ -4972,10 +4913,6 @@ if (src_elem != dest_elem || dest_elem == T_VOID) { // The component types are not the same or are not recognized. Punt. // (But, avoid the native method wrapper to JVM_ArrayCopy.) - - src = shenandoah_read_barrier(src); - dest = shenandoah_write_barrier(dest); - generate_slow_arraycopy(TypePtr::BOTTOM, src, src_offset, dest, dest_offset, length, /*dest_uninitialized*/false); @@ -5041,9 +4978,6 @@ src = null_check(src, T_ARRAY); dest = null_check(dest, T_ARRAY); - src = shenandoah_read_barrier(src); - dest = shenandoah_write_barrier(dest); - // (4) src_offset must not be negative. generate_negative_guard(src_offset, slow_region); @@ -5512,8 +5446,6 @@ if (stopped()) return NULL; // no fast path if (C->AliasLevel() == 0) return NULL; // no MergeMems around - ptr = ShenandoahBarrierNode::skip_through_barrier(ptr); - AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn); if (alloc == NULL) return NULL; @@ -5892,12 +5824,6 @@ Node *dst_offset = argument(3); Node *length = argument(4); - src = shenandoah_cast_not_null(src); - dst = shenandoah_cast_not_null(dst); - - src = shenandoah_read_barrier(src); - dst = shenandoah_write_barrier(dst); - const Type* src_type = src->Value(&_gvn); const Type* dst_type = dst->Value(&_gvn); const TypeAryPtr* top_src = src_type->isa_aryptr(); @@ -5947,12 +5873,6 @@ Node* ylen = argument(3); Node* z = argument(4); - x = shenandoah_cast_not_null(x); - x = shenandoah_read_barrier(x); - y = shenandoah_cast_not_null(y); - y = shenandoah_read_barrier(y); - z = shenandoah_write_barrier(z); - const Type* x_type = x->Value(&_gvn); const Type* y_type = y->Value(&_gvn); const TypeAryPtr* top_x = x_type->isa_aryptr(); @@ -5998,16 +5918,7 @@ } __ else_(); { // Update graphKit memory and control from IdealKit. sync_kit(ideal); - Node* zlen_arg = NULL; - if (UseShenandoahGC) { - Node *cast = new (C) CastPPNode(z, TypePtr::NOTNULL); - cast->init_req(0, control()); - _gvn.set_type(cast, cast->bottom_type()); - C->record_for_igvn(cast); - zlen_arg = load_array_length(cast); - } else { - zlen_arg = load_array_length(z); - } + Node* zlen_arg = load_array_length(z); // Update IdealKit memory and control from graphKit. __ sync_kit(this); __ if_then(zlen_arg, BoolTest::lt, zlen); { @@ -6062,11 +5973,6 @@ Node* z = argument(2); Node* zlen = argument(3); - x = shenandoah_cast_not_null(x); - x = shenandoah_read_barrier(x); - z = shenandoah_cast_not_null(z); - z = shenandoah_write_barrier(z); - const Type* x_type = x->Value(&_gvn); const Type* z_type = z->Value(&_gvn); const TypeAryPtr* top_x = x_type->isa_aryptr(); @@ -6114,10 +6020,6 @@ Node* len = argument(3); Node* k = argument(4); - in = shenandoah_read_barrier(in); - out = shenandoah_cast_not_null(out); - out = shenandoah_write_barrier(out); - const Type* out_type = out->Value(&_gvn); const Type* in_type = in->Value(&_gvn); const TypeAryPtr* top_out = out_type->isa_aryptr(); @@ -6167,11 +6069,6 @@ Node* inv = argument(4); Node* m = argument(6); - a = shenandoah_read_barrier(a); - b = shenandoah_read_barrier(b); - n = shenandoah_read_barrier(n); - m = shenandoah_write_barrier(m); - const Type* a_type = a->Value(&_gvn); const TypeAryPtr* top_a = a_type->isa_aryptr(); const Type* b_type = b->Value(&_gvn); @@ -6241,10 +6138,6 @@ Node* inv = argument(3); Node* m = argument(5); - a = shenandoah_read_barrier(a); - n = shenandoah_read_barrier(n); - m = shenandoah_write_barrier(m); - const Type* a_type = a->Value(&_gvn); const TypeAryPtr* top_a = a_type->isa_aryptr(); const Type* n_type = a->Value(&_gvn); @@ -6356,9 +6249,6 @@ } // 'src_start' points to src array + scaled offset - src = shenandoah_cast_not_null(src); - src = shenandoah_read_barrier(src); - src = shenandoah_read_barrier(src); Node* src_start = array_element_address(src, offset, src_elem); // We assume that range check is done by caller. @@ -6438,6 +6328,12 @@ Node* no_ctrl = NULL; Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + result = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, result); + } +#endif + // Use the pre-barrier to record the value in the referent field pre_barrier(false /* do_load */, control(), @@ -6468,14 +6364,6 @@ if (field == NULL) return (Node *) NULL; assert (field != NULL, "undefined field"); - if ((ShenandoahOptimizeStaticFinals && field->is_static() && field->is_final()) || - (ShenandoahOptimizeInstanceFinals && !field->is_static() && field->is_final()) || - (ShenandoahOptimizeStableFinals && field->is_stable())) { - // Skip the barrier for special fields - } else { - fromObj = shenandoah_read_barrier(fromObj); - } - // Next code copied from Parse::do_get_xxx(): // Compute address and memory type. @@ -6502,6 +6390,12 @@ // Build the load. MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered; Node* loadedField = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, is_vol); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (bt == T_OBJECT || bt == T_ARRAY)) { + loadedField = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, loadedField); + } +#endif + // If reference is volatile, prevent following memory ops from // floating up past the volatile read. Also prevents commoning // another volatile read. @@ -6538,12 +6432,6 @@ Node* dest = argument(3); Node* dest_offset = argument(4); - // Resolve src and dest arrays for ShenandoahGC. - src = shenandoah_cast_not_null(src); - src = shenandoah_read_barrier(src); - dest = shenandoah_cast_not_null(dest); - dest = shenandoah_write_barrier(dest); - // (1) src and dest are arrays. const Type* src_type = src->Value(&_gvn); const Type* dest_type = dest->Value(&_gvn); @@ -6612,13 +6500,6 @@ Node* dest = argument(4); Node* dest_offset = argument(5); - // inline_cipherBlockChaining_AESCrypt_predicate() has its own - // barrier. This one should optimize away. - src = shenandoah_cast_not_null(src); - dest = shenandoah_cast_not_null(dest); - src = shenandoah_read_barrier(src); - dest = shenandoah_write_barrier(dest); - // (1) src and dest are arrays. const Type* src_type = src->Value(&_gvn); const Type* dest_type = dest->Value(&_gvn); @@ -6663,9 +6544,6 @@ // similarly, get the start address of the r vector Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false); - - objRvec = shenandoah_write_barrier(objRvec); - if (objRvec == NULL) return false; Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE); @@ -6714,8 +6592,6 @@ assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt"); if (objAESCryptKey == NULL) return (Node *) NULL; - objAESCryptKey = shenandoah_read_barrier(objAESCryptKey); - // now have the array, need to get the start address of the K array Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT); return k_start; @@ -6727,8 +6603,6 @@ assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt"); if (objAESCryptKey == NULL) return (Node *) NULL; - objAESCryptKey = shenandoah_read_barrier(objAESCryptKey); - // now have the array, need to get the start address of the lastKey array Node* original_k_start = array_element_address(objAESCryptKey, intcon(0), T_BYTE); return original_k_start; @@ -6747,9 +6621,6 @@ // The receiver was checked for NULL already. Node* objCBC = argument(0); - Node* src = argument(1); - Node* dest = argument(4); - // Load embeddedCipher field of CipherBlockChaining object. Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false); @@ -6768,15 +6639,6 @@ set_control(top()); // no regular fast path return ctrl; } - - // Resolve src and dest arrays for ShenandoahGC. Here because new - // memory state is not handled by predicate logic in - // inline_cipherBlockChaining_AESCrypt itself - src = shenandoah_cast_not_null(src); - dest = shenandoah_cast_not_null(dest); - src = shenandoah_write_barrier(src); - dest = shenandoah_write_barrier(dest); - ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt))); @@ -6794,7 +6656,8 @@ // see the original java code for why. RegionNode* region = new(C) RegionNode(3); region->init_req(1, instof_false); - + Node* src = argument(1); + Node* dest = argument(4); Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest)); Node* bool_src_dest = _gvn.transform(new (C) BoolNode(cmp_src_dest, BoolTest::eq)); Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN); @@ -6804,6 +6667,35 @@ return _gvn.transform(region); } +//------------------------------inline_ghash_processBlocks +bool LibraryCallKit::inline_ghash_processBlocks() { + address stubAddr; + const char *stubName; + assert(UseGHASHIntrinsics, "need GHASH intrinsics support"); + + stubAddr = StubRoutines::ghash_processBlocks(); + stubName = "ghash_processBlocks"; + + Node* data = argument(0); + Node* offset = argument(1); + Node* len = argument(2); + Node* state = argument(3); + Node* subkeyH = argument(4); + + Node* state_start = array_element_address(state, intcon(0), T_LONG); + assert(state_start, "state is NULL"); + Node* subkeyH_start = array_element_address(subkeyH, intcon(0), T_LONG); + assert(subkeyH_start, "subkeyH is NULL"); + Node* data_start = array_element_address(data, offset, T_BYTE); + assert(data_start, "data is NULL"); + + Node* ghash = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::ghash_processBlocks_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + state_start, subkeyH_start, data_start, len); + return true; +} + //------------------------------inline_sha_implCompress----------------------- // // Calculate SHA (i.e., SHA-1) for single-block byte[] array. @@ -6834,8 +6726,6 @@ return false; } // 'src_start' points to src array + offset - src = cast_not_null(src, false); - src = shenandoah_read_barrier(src); Node* src_start = array_element_address(src, ofs, src_elem); Node* state = NULL; address stubAddr; @@ -6902,8 +6792,6 @@ return false; } // 'src_start' points to src array + offset - src = shenandoah_cast_not_null(src); - src = shenandoah_read_barrier(src); Node* src_start = array_element_address(src, ofs, src_elem); const char* klass_SHA_name = NULL; @@ -6993,8 +6881,6 @@ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2"); if (sha_state == NULL) return (Node *) NULL; - sha_state = shenandoah_write_barrier(sha_state); - // now have the array, need to get the start address of the state array Node* state = array_element_address(sha_state, intcon(0), T_INT); return state; @@ -7006,8 +6892,6 @@ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5"); if (sha_state == NULL) return (Node *) NULL; - sha_state = shenandoah_write_barrier(sha_state); - // now have the array, need to get the start address of the state array Node* state = array_element_address(sha_state, intcon(0), T_LONG); return state; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,6 +37,10 @@ #include "opto/rootnode.hpp" #include "opto/superword.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif + //============================================================================= //------------------------------is_loop_iv------------------------------------- // Determine if a node is Counted loop induction variable. @@ -2347,9 +2351,11 @@ C->set_major_progress(); } +#if INCLUDE_ALL_GCS if (UseShenandoahGC && !C->major_progress()) { - shenandoah_pin_and_expand_barriers(); + ShenandoahBarrierC2Support::pin_and_expand(this); } +#endif // Cleanup any modified bits _igvn.optimize(); @@ -3540,8 +3546,6 @@ case Op_StrEquals: case Op_StrIndexOf: case Op_AryEq: - case Op_ShenandoahReadBarrier: - case Op_ShenandoahWriteBarrier: pinned = false; } if( pinned ) { @@ -3598,27 +3602,33 @@ // which can inhibit range check elimination. if (least != early) { Node* ctrl_out = least->unique_ctrl_out(); - if (UseShenandoahGC && - ctrl_out && ctrl_out->is_Loop() && + if (UseShenandoahGC && ctrl_out && ctrl_out->is_Loop() && least == ctrl_out->in(LoopNode::EntryControl)) { + // Move the node above predicates as far up as possible so a + // following pass of loop predication doesn't hoist a predicate + // that depends on it above that node. Node* new_ctrl = least; - if (find_predicate_insertion_point(new_ctrl, Deoptimization::Reason_loop_limit_check) != NULL) { - new_ctrl = new_ctrl->in(0)->in(0); - assert(is_dominator(early, new_ctrl), "least != early so we can move up the dominator tree"); - } - if (find_predicate_insertion_point(new_ctrl, Deoptimization::Reason_predicate) != NULL) { + for (;;) { + if (!new_ctrl->is_Proj()) { + break; + } + CallStaticJavaNode* call = new_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); + if (call == NULL) { + break; + } + int req = call->uncommon_trap_request(); + Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); + if (trap_reason != Deoptimization::Reason_loop_limit_check && + trap_reason != Deoptimization::Reason_predicate) { + break; + } Node* c = new_ctrl->in(0)->in(0); - assert(is_dominator(early, c), "least != early so we can move up the dominator tree"); - new_ctrl = c; - } - if (new_ctrl != least) { - least = new_ctrl; - } else if (ctrl_out->is_CountedLoop()) { - Node* least_dom = idom(least); - if (get_loop(least_dom)->is_member(get_loop(least))) { - least = least_dom; + if (is_dominator(c, early) && c != early) { + break; } + new_ctrl = c; } + least = new_ctrl; } else if (ctrl_out && ctrl_out->is_CountedLoop() && least == ctrl_out->in(LoopNode::EntryControl)) { Node* least_dom = idom(least); @@ -3651,16 +3661,6 @@ IdealLoopTree *chosen_loop = get_loop(least); if( !chosen_loop->_child ) // Inner loop? chosen_loop->_body.push(n);// Collect inner loops - - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - // The write barrier and its memory proj must have the same - // control otherwise some loop opts could put nodes (Phis) between - // them - Node* proj = n->find_out_with(Op_ShenandoahWBMemProj); - if (proj != NULL) { - set_ctrl_and_loop(proj, least); - } - } } #ifdef ASSERT diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopnode.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopnode.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopnode.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopnode.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -279,6 +279,7 @@ if (iv_phi == NULL) { return NULL; } + assert(iv_phi->is_Phi(), "should be PhiNode"); Node *ln = iv_phi->in(0); if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) { return (CountedLoopNode*)ln; @@ -1046,7 +1047,6 @@ Node *split_thru_region( Node *n, Node *region ); // Split Node 'n' through merge point if there is enough win. Node *split_thru_phi( Node *n, Node *region, int policy ); - void split_mem_thru_phi(Node*, Node* r, Node* phi); // Found an If getting its condition-code input from a Phi in the // same block. Split thru the Region. @@ -1073,48 +1073,6 @@ void sink_use( Node *use, Node *post_loop ); Node *place_near_use( Node *useblock ) const; - Node* try_common_shenandoah_barriers(Node* n, Node *n_ctrl); - MergeMemNode* shenandoah_allocate_merge_mem(Node* mem, int alias, Node* rep_proj, Node* rep_ctrl); - bool shenandoah_should_process_phi(Node* phi, int alias); - MergeMemNode* shenandoah_clone_merge_mem(Node* u, Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, DUIterator& i); - Node* shenandoah_no_branches(Node* c, Node* dom, bool allow_one_proj); - Node* try_move_shenandoah_barrier_before_loop(Node* n, Node *n_ctrl); -#ifdef ASSERT - bool shenandoah_memory_dominates_all_paths(Node* mem, Node* rep_ctrl, int alias); - void shenandoah_memory_dominates_all_paths_helper(Node* c, Node* rep_ctrl, Unique_Node_List& controls); -#endif - bool shenandoah_fix_mem_phis(Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias); - bool shenandoah_fix_mem_phis_helper(Node* c, Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias, VectorSet& controls, GrowableArray& phis); - void try_move_shenandoah_read_barrier(Node* n, Node *n_ctrl); - Node* shenandoah_dom_mem(Node* mem, Node*& mem_ctrl, Node* n, Node* rep_ctrl, int alias); - Node* try_move_shenandoah_barrier_before_pre_loop(Node* c, Node* val_ctrl); - Node* try_move_shenandoah_barrier_before_loop_helper(Node* n, Node* cl, Node* val_ctrl, Node* mem); - Node* shenandoah_move_above_predicates(Node* cl, Node* val_ctrl); - void shenandoah_pin_and_expand_barriers(); - CallStaticJavaNode* shenandoah_pin_and_expand_barriers_null_check(ShenandoahBarrierNode* wb); - void shenandoah_pin_and_expand_barriers_move_barrier(ShenandoahBarrierNode* wb); - Node* shenandoah_pick_phi(Node* phi1, Node* phi2, Node_Stack& phis, VectorSet& visited); - Node* shenandoah_find_bottom_mem(Node* ctrl); - void shenandoah_follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses); - bool shenandoah_already_has_better_phi(Node* region, int alias, Node* m, Node* m_ctrl); - void shenandoah_fix_raw_mem(Node* ctrl, Node* region, Node* raw_mem, Node* raw_mem_for_ctrl, - Node* raw_mem_phi, Node_List& memory_nodes, - Unique_Node_List& uses); - void shenandoah_test_evacuation_in_progress(Node* ctrl, int alias, Node*& raw_mem, Node*& wb_mem, - IfNode*& evacuation_iff, Node*& evac_in_progress, - Node*& evac_not_in_progress); - void shenandoah_evacuation_not_in_progress(Node* c, Node* v, Node* unc_ctrl, Node* raw_mem, Node* wb_mem, Node* region, - Node* val_phi, Node* mem_phi, Node* raw_mem_phi, Node*& unc_region); - void shenandoah_evacuation_in_progress(Node* c, Node* val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, - Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, Node* mem_phi, - Node* raw_mem_phi, Node* unc_region, int alias, Unique_Node_List& uses); - void shenandoah_evacuation_not_in_progress_null_check(Node*& c, Node*& val, Node* unc_ctrl, Node*& unc_region); - void shenandoah_evacuation_in_progress_null_check(Node*& c, Node*& val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, - Node* unc_region, Unique_Node_List& uses); - void shenandoah_in_cset_fast_test(Node*& c, Node* rbtrue, Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, - Node* mem_phi, Node* raw_mem_phi); - Node* shenandoah_get_ctrl(Node* n); - bool _created_loop_node; public: void set_created_loop_node() { _created_loop_node = true; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopopts.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopopts.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopopts.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopopts.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -31,8 +31,10 @@ #include "opto/matcher.hpp" #include "opto/mulnode.hpp" #include "opto/rootnode.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif //============================================================================= //------------------------------split_thru_phi--------------------------------- @@ -118,7 +120,7 @@ // otherwise it will be not updated during igvn->transform since // igvn->type(x) is set to x->Value() already. x->raise_bottom_type(t); - if (x->Opcode() != Op_ShenandoahWriteBarrier) { + if (x->Opcode() != Op_ShenandoahLoadReferenceBarrier) { Node *y = x->Identity(&_igvn); if (y != x) { wins++; @@ -205,44 +207,6 @@ return phi; } -/** - * When splitting a Shenandoah write barrier through a phi, we - * can not replace the write-barrier input of the ShenandoahWBMemProj - * with the phi. We must also split the ShenandoahWBMemProj through the - * phi and generate a new memory phi for it. - */ -void PhaseIdealLoop::split_mem_thru_phi(Node* n, Node* r, Node* phi) { - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - if (n->has_out_with(Op_ShenandoahWBMemProj)) { - Node* old_mem_phi = n->in(ShenandoahBarrierNode::Memory); - assert(r->is_Region(), "need region to control phi"); - assert(phi->is_Phi(), "expect phi"); - Node* memphi = PhiNode::make(r, old_mem_phi, Type::MEMORY, C->alias_type(n->adr_type())->adr_type()); - for (uint i = 1; i < r->req(); i++) { - Node* wb = phi->in(i); - if (wb->Opcode() == Op_ShenandoahWriteBarrier) { - // assert(! wb->has_out_with(Op_ShenandoahWBMemProj), "new clone does not have mem proj"); - Node* new_proj = new (C) ShenandoahWBMemProjNode(wb); - register_new_node(new_proj, r->in(i)); - memphi->set_req(i, new_proj); - } else { - if (old_mem_phi->is_Phi() && old_mem_phi->in(0) == r) { - memphi->set_req(i, old_mem_phi->in(i)); - } - } - } - register_new_node(memphi, r); - Node* old_mem_out = n->find_out_with(Op_ShenandoahWBMemProj); - while (old_mem_out != NULL) { - assert(old_mem_out != NULL, "expect memory projection"); - _igvn.replace_node(old_mem_out, memphi); - old_mem_out = n->find_out_with(Op_ShenandoahWBMemProj); - } - } - assert(! n->has_out_with(Op_ShenandoahWBMemProj), "no more memory outs"); - } -} - //------------------------------dominated_by------------------------------------ // Replace the dominated test with an obvious true or false. Place it on the // IGVN worklist for later cleanup. Move control-dependent data Nodes on the @@ -353,7 +317,7 @@ } return NULL; } - assert(m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); + assert(n->is_Phi() || m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); } return n_ctrl; @@ -739,15 +703,6 @@ Node *n_ctrl = get_ctrl(n); if( !n_ctrl ) return n; // Dead node - try_move_shenandoah_barrier_before_loop(n, n_ctrl); - - Node* res = try_common_shenandoah_barriers(n, n_ctrl); - if (res != NULL) { - return res; - } - - try_move_shenandoah_read_barrier(n, n_ctrl); - // Attempt to remix address expressions for loop invariants Node *m = remix_address_expressions( n ); if( m ) return m; @@ -791,7 +746,6 @@ // Found a Phi to split thru! // Replace 'n' with the new phi - split_mem_thru_phi(n, n_blk, phi); _igvn.replace_node( n, phi ); // Moved a load around the loop, 'en-registering' something. if (n_blk->is_Loop() && n->is_Load() && @@ -799,8 +753,8 @@ C->set_major_progress(); // Moved a barrier around the loop, 'en-registering' something. - if (n_blk->is_Loop() && n->is_ShenandoahBarrier() && - !phi->in(LoopNode::LoopBackControl)->is_ShenandoahBarrier()) + if (n_blk->is_Loop() && n->Opcode() == Op_ShenandoahLoadReferenceBarrier && + phi->in(LoopNode::LoopBackControl)->Opcode() != Op_ShenandoahLoadReferenceBarrier) C->set_major_progress(); return phi; @@ -1065,7 +1019,7 @@ // For inner loop uses get the preheader area. x_ctrl = place_near_use(x_ctrl); - if (n->is_Load() || n->Opcode() == Op_ShenandoahReadBarrier) { + if (n->is_Load()) { // For loads, add a control edge to a CFG node outside of the loop // to force them to not combine and return back inside the loop // during GVN optimization (4641526). @@ -1073,9 +1027,7 @@ // Because we are setting the actual control input, factor in // the result from get_late_ctrl() so we respect any // anti-dependences. (6233005). - if (n->is_Load()) { x_ctrl = dom_lca(late_load_ctrl, x_ctrl); - } // Don't allow the control input to be a CFG splitting node. // Such nodes should only have ProjNodes as outs, e.g. IfNode @@ -1097,7 +1049,7 @@ // to fold a StoreP and an AddP together (as part of an // address expression) and the AddP and StoreP have // different controls. - if (!x->is_Load() && !x->is_DecodeNarrowPtr() && !x->is_ShenandoahBarrier()) _igvn._worklist.yank(x); + if (!x->is_Load() && !x->is_DecodeNarrowPtr()) _igvn._worklist.yank(x); } _igvn.remove_dead_node(n); } @@ -1531,13 +1483,12 @@ // private Phi and those Phis need to be merged here. Node *phi; if( prev->is_Region() ) { - if( idx == 0 && use->Opcode() != Op_ShenandoahWBMemProj) { // Updating control edge? + if( idx == 0 ) { // Updating control edge? phi = prev; // Just use existing control } else { // Else need a new Phi phi = PhiNode::make( prev, old ); // Now recursively fix up the new uses of old! - uint first = use->Opcode() != Op_ShenandoahWBMemProj ? 1 : 0; - for( uint i = first; i < prev->req(); i++ ) { + for( uint i = 1; i < prev->req(); i++ ) { worklist.push(phi); // Onto worklist once for each 'old' input } } @@ -1545,7 +1496,7 @@ // Get new RegionNode merging old and new loop exits prev = old_new[prev->_idx]; assert( prev, "just made this in step 7" ); - if( idx == 0 && use->Opcode() != Op_ShenandoahWBMemProj) { // Updating control edge? + if( idx == 0 ) { // Updating control edge? phi = prev; // Just use existing control } else { // Else need a new Phi // Make a new Phi merging data values properly diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopPredicate.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopPredicate.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopPredicate.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopPredicate.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -409,7 +409,7 @@ if (_lpt->is_invariant(n)) { // known invariant _invariant.set(n->_idx); } else if (!n->is_CFG()) { - if (n->Opcode() == Op_ShenandoahWriteBarrier) { + if (n->Opcode() == Op_ShenandoahLoadReferenceBarrier) { return; } Node *n_ctrl = _phase->ctrl_or_self(n); @@ -446,7 +446,7 @@ // loop, it was marked invariant but n is only invariant if // it depends only on that test. Otherwise, unless that test // is out of the loop, it's not invariant. - if (n->Opcode() == Op_ShenandoahWBMemProj || n->is_CFG() || n->depends_only_on_test() || n->in(0) == NULL || !_phase->is_member(_lpt, n->in(0))) { + if (n->is_CFG() || n->depends_only_on_test() || n->in(0) == NULL || !_phase->is_member(_lpt, n->in(0))) { _invariant.set(n->_idx); // I am a invariant too } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopTransform.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopTransform.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/loopTransform.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/loopTransform.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -861,11 +861,7 @@ // Recursive fixup any other input edges into x. // If there are no changes we can just return 'n', otherwise // we need to clone a private copy and change it. - uint start = 1; - if (n->Opcode() == Op_ShenandoahWBMemProj) { - start = 0; - } - for( uint i = start; i < n->req(); i++ ) { + for( uint i = 1; i < n->req(); i++ ) { Node *g = clone_up_backedge_goo( back_ctrl, preheader_ctrl, n->in(i), visited, clones ); if( g != n->in(i) ) { if( !x ) { @@ -2235,6 +2231,13 @@ // We also need to replace the original limit to collapse loop exit. Node* cmp = cl->loopexit()->cmp_node(); assert(cl->limit() == cmp->in(2), "sanity"); + // Duplicate cmp node if it has other users + if (cmp->outcnt() > 1) { + cmp = cmp->clone(); + cmp = phase->_igvn.register_new_node_with_optimizer(cmp); + BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool(); + phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist + } phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/machnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/machnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/machnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/machnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -26,7 +26,9 @@ #include "gc_interface/collectedHeap.hpp" #include "opto/machnode.hpp" #include "opto/regalloc.hpp" -#include "opto/shenandoahSupport.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif //============================================================================= // Return the value requested diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/macro.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/macro.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/macro.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/macro.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "compiler/compileLog.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "libadt/vectset.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" @@ -39,10 +38,14 @@ #include "opto/phaseX.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" #include "opto/type.hpp" #include "runtime/sharedRuntime.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // @@ -446,7 +449,13 @@ if (val == mem) { values.at_put(j, mem); } else if (val->is_Store()) { - values.at_put(j, ShenandoahBarrierNode::skip_through_barrier(val->in(MemNode::ValueIn))); + Node* n = val->in(MemNode::ValueIn); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + n = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(n); + } +#endif + values.at_put(j, n); } else if(val->is_Proj() && val->in(0) == alloc) { values.at_put(j, _igvn.zerocon(ft)); } else if (val->is_Phi()) { @@ -548,7 +557,13 @@ // hit a sentinel, return appropriate 0 value return _igvn.zerocon(ft); } else if (mem->is_Store()) { - return ShenandoahBarrierNode::skip_through_barrier(mem->in(MemNode::ValueIn)); + Node* n = mem->in(MemNode::ValueIn); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + n = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(n); + } +#endif + return n; } else if (mem->is_Phi()) { // attempt to produce a Phi reflecting the values on the input paths of the Phi Node_Stack value_phis(a, 8); @@ -1290,14 +1305,6 @@ transform_later(old_eden_top); // Add to heap top to get a new heap top - - Node* init_size_in_bytes = size_in_bytes; - if (UseShenandoahGC) { - // Allocate several words more for the Shenandoah brooks pointer. - size_in_bytes = new (C) AddXNode(size_in_bytes, _igvn.MakeConX(ShenandoahBrooksPointer::byte_size())); - transform_later(size_in_bytes); - } - Node *new_eden_top = new (C) AddPNode(top(), old_eden_top, size_in_bytes); transform_later(new_eden_top); // Check for needing a GC; compare against heap end @@ -1388,16 +1395,10 @@ 0, new_alloc_bytes, T_LONG); } - if (UseShenandoahGC) { - // Bump up object for Shenandoah brooks pointer. - fast_oop = new (C) AddPNode(top(), fast_oop, _igvn.MakeConX(ShenandoahBrooksPointer::byte_size())); - transform_later(fast_oop); - } - InitializeNode* init = alloc->initialization(); fast_oop_rawmem = initialize_object(alloc, fast_oop_ctrl, fast_oop_rawmem, fast_oop, - klass_node, length, init_size_in_bytes); + klass_node, length, size_in_bytes); // If initialization is performed by an array copy, any required // MemBarStoreStore was already added. If the object does not @@ -1677,11 +1678,6 @@ header_size = Klass::layout_helper_header_size(k->layout_helper()); } - if (UseShenandoahGC) { - // Initialize Shenandoah brooks pointer to point to the object itself. - rawmem = make_store(control, rawmem, object, ShenandoahBrooksPointer::byte_offset(), object, T_OBJECT); - } - // Clear the object body, if necessary. if (init == NULL) { // The init has somehow disappeared; be cautious and clear everything. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/matcher.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/matcher.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/matcher.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/matcher.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,7 +34,6 @@ #include "opto/regmask.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/type.hpp" #include "opto/vectornode.hpp" #include "runtime/atomic.hpp" @@ -54,6 +53,9 @@ #elif defined TARGET_ARCH_MODEL_ppc_64 # include "adfiles/ad_ppc_64.hpp" #endif +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif OptoReg::Name OptoReg::c_frame_pointer; @@ -2166,13 +2168,6 @@ case Op_SafePoint: mem_op = true; break; - case Op_ShenandoahReadBarrier: - if (n->in(ShenandoahBarrierNode::ValueIn)->is_DecodeNarrowPtr()) { - set_shared(n->in(ShenandoahBarrierNode::ValueIn)->in(1)); - } - mem_op = true; - set_shared(n); - break; default: if( n->is_Store() ) { // Do match stores, despite no ideal reg diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/memnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/memnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/memnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/memnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "compiler/compileLog.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "memory/allocation.inline.hpp" #include "oops/objArrayKlass.hpp" #include "opto/addnode.hpp" @@ -39,7 +38,11 @@ #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" #include "opto/regmask.hpp" -#include "opto/shenandoahSupport.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -898,7 +901,11 @@ (tp != NULL) && tp->is_ptr_to_boxed_value()) { intptr_t ignore = 0; Node* base = AddPNode::Ideal_base_and_offset(ld_adr, phase, ignore); - base = ShenandoahBarrierNode::skip_through_barrier(base); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + base = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(base); + } +#endif if (base != NULL && base->is_Proj() && base->as_Proj()->_con == TypeFunc::Parms && base->in(0)->is_CallStaticJava() && @@ -954,7 +961,7 @@ value->is_Phi() && value->req() > 2 && value->in(1) != NULL && - value->in(1)->is_ShenandoahBarrier()) { + value->in(1)->Opcode() == Op_ShenandoahLoadReferenceBarrier) { if (igvn->_worklist.member(value) || igvn->_worklist.member(value->in(0)) || (value->in(0)->in(1) != NULL && @@ -968,8 +975,9 @@ } // (This works even when value is a Con, but LoadNode::Value // usually runs first, producing the singleton type of the Con.) - if (UseShenandoahGC) { - Node* value_no_barrier = ShenandoahBarrierNode::skip_through_barrier(value->Opcode() == Op_EncodeP ? value->in(1) : value); + // TODO!! + if (false && UseShenandoahGC) { + Node* value_no_barrier = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(value->Opcode() == Op_EncodeP ? value->in(1) : value); if (value->Opcode() == Op_EncodeP) { if (value_no_barrier != value->in(1)) { Node* encode = value->clone(); @@ -1044,7 +1052,7 @@ return NULL; // Complex address } AddPNode* address = base->in(Address)->as_AddP(); - Node* cache_base = ShenandoahBarrierNode::skip_through_barrier(address->in(AddPNode::Base)); + Node* cache_base = address->in(AddPNode::Base); if ((cache_base != NULL) && cache_base->is_DecodeN()) { // Get ConP node which is static 'cache' field. cache_base = cache_base->in(1); @@ -1517,21 +1525,12 @@ // as to alignment, which will therefore produce the smallest // possible base offset. const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); - const bool off_beyond_header = (off != ShenandoahBrooksPointer::byte_offset() || !UseShenandoahGC) && ((uint)off >= (uint)min_base_off); + const bool off_beyond_header = ((uint)off >= (uint)min_base_off); // Try to constant-fold a stable array element. if (FoldStableValues && ary->is_stable()) { // Make sure the reference is not into the header and the offset is constant - ciObject* aobj = NULL; - if (UseShenandoahGC && adr->is_AddP() && !adr->in(AddPNode::Base)->is_top()) { - Node* base = ShenandoahBarrierNode::skip_through_barrier(adr->in(AddPNode::Base)); - if (!base->is_top()) { - ary = phase->type(base)->is_aryptr(); - aobj = ary->const_oop(); - } - } else { - aobj = ary->const_oop(); - } + ciObject* aobj = ary->const_oop(); if (aobj != NULL && off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) { const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); if (con_type != NULL) { @@ -1621,19 +1620,7 @@ } } // Optimizations for constant objects - ciObject* const_oop = NULL; - if (UseShenandoahGC && adr->is_AddP() && !adr->in(AddPNode::Base)->is_top()) { - Node* base = ShenandoahBarrierNode::skip_through_barrier(adr->in(AddPNode::Base)); - if (phase->type(base) != Type::TOP) { - const TypePtr* base_t = phase->type(base)->is_ptr(); - if (base_t != TypePtr::NULL_PTR) { - tinst = base_t->is_instptr(); - const_oop = tinst->const_oop(); - } - } - } else { - const_oop = tinst->const_oop(); - } + ciObject* const_oop = tinst->const_oop(); if (const_oop != NULL) { // For constant Boxed value treat the target field as a compile time constant. if (tinst->is_ptr_to_boxed_value()) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/mulnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/mulnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/mulnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/mulnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -29,9 +29,11 @@ #include "opto/memnode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" #include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -476,7 +478,7 @@ uint lop = load->Opcode(); #if INCLUDE_ALL_GCS - if (UseShenandoahGC && ShenandoahWriteBarrierNode::is_gc_state_load(load)) { + if (UseShenandoahGC && ShenandoahBarrierC2Support::is_gc_state_load(load)) { // Do not touch the load+mask, we would match the whole sequence exactly. // Converting the load to LoadUB/LoadUS would mismatch and waste a register // on the barrier fastpath. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/multnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/multnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/multnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/multnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -31,8 +31,10 @@ #include "opto/opcodes.hpp" #include "opto/phaseX.hpp" #include "opto/regmask.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/type.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif //============================================================================= //------------------------------MultiNode-------------------------------------- @@ -126,7 +128,6 @@ if (n->is_Mach()) return; // mach. projs. are not type-safe if (n->is_Start()) return; // alas, starts can have mach. projs. also if (_con == SCMemProjNode::SCMEMPROJCON ) return; - if (_con == ShenandoahWBMemProjNode::SWBMEMPROJCON ) return; const Type* t = n->bottom_type(); if (t == Type::TOP) return; // multi is dead assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/node.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/node.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/node.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/node.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -33,9 +33,11 @@ #include "opto/node.hpp" #include "opto/opcodes.hpp" #include "opto/regmask.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/type.hpp" #include "utilities/copy.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif class RegMask; // #include "phase.hpp" @@ -523,8 +525,8 @@ if (is_expensive()) C->add_expensive_node(n); - if (Opcode() == Op_ShenandoahWriteBarrier) { - C->add_shenandoah_barrier(n->as_ShenandoahBarrier()); + if (Opcode() == Op_ShenandoahLoadReferenceBarrier) { + C->add_shenandoah_barrier(reinterpret_cast(n)); } // If the cloned node is a range check dependent CastII, add it to the list. CastIINode* cast = n->isa_CastII(); @@ -659,8 +661,8 @@ if (is_expensive()) { compile->remove_expensive_node(this); } - if (is_ShenandoahBarrier()) { - compile->remove_shenandoah_barrier(this->as_ShenandoahBarrier()); + if (Opcode() == Op_ShenandoahLoadReferenceBarrier) { + compile->remove_shenandoah_barrier(reinterpret_cast(this)); } CastIINode* cast = isa_CastII(); if (cast != NULL && cast->has_range_check()) { @@ -1160,8 +1162,6 @@ } else if( op == Op_SubI || op == Op_SubL ) { // Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y) return n->Opcode() == op && n->in(2) == this; - } else if (op == Op_ShenandoahWriteBarrier) { - return n->Opcode() == Op_ShenandoahWBMemProj; } return false; }; @@ -1380,8 +1380,8 @@ if (dead->is_expensive()) { igvn->C->remove_expensive_node(dead); } - if (dead->is_ShenandoahBarrier()) { - igvn->C->remove_shenandoah_barrier(dead->as_ShenandoahBarrier()); + if (dead->Opcode() == Op_ShenandoahLoadReferenceBarrier) { + igvn->C->remove_shenandoah_barrier(reinterpret_cast(dead)); } CastIINode* cast = dead->isa_CastII(); if (cast != NULL && cast->has_range_check()) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse2.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse2.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse2.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse2.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -40,17 +40,26 @@ #include "runtime/deoptimization.hpp" #include "runtime/sharedRuntime.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#endif + extern int explicit_null_checks_inserted, explicit_null_checks_elided; //---------------------------------array_load---------------------------------- void Parse::array_load(BasicType elem_type) { const Type* elem = Type::TOP; - Node* adr = array_addressing(elem_type, 0, false, &elem); + Node* adr = array_addressing(elem_type, 0, &elem); if (stopped()) return; // guaranteed null or range check dec_sp(2); // Pop array and index const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type); Node* ld = make_load(control(), adr, elem, elem_type, adr_type, MemNode::unordered); +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (elem_type == T_OBJECT || elem_type == T_ARRAY)) { + ld = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, ld); + } +#endif push(ld); } @@ -58,7 +67,7 @@ //--------------------------------array_store---------------------------------- void Parse::array_store(BasicType elem_type) { const Type* elem = Type::TOP; - Node* adr = array_addressing(elem_type, 1, true, &elem); + Node* adr = array_addressing(elem_type, 1, &elem); if (stopped()) return; // guaranteed null or range check Node* val = pop(); dec_sp(2); // Pop array and index @@ -72,7 +81,7 @@ //------------------------------array_addressing------------------------------- // Pull array and index from the stack. Compute pointer-to-element. -Node* Parse::array_addressing(BasicType type, int vals, bool is_store, const Type* *result2) { +Node* Parse::array_addressing(BasicType type, int vals, const Type* *result2) { Node *idx = peek(0+vals); // Get from stack without popping Node *ary = peek(1+vals); // in case of exception @@ -158,12 +167,6 @@ // Check for always knowing you are throwing a range-check exception if (stopped()) return top(); - if (is_store) { - ary = shenandoah_write_barrier(ary); - } else { - ary = shenandoah_read_barrier(ary); - } - // Make array address computation control dependent to prevent it // from floating above the range check during loop optimizations. Node* ptr = array_element_address(ary, idx, type, sizetype, control()); @@ -1708,14 +1711,14 @@ case Bytecodes::_faload: array_load(T_FLOAT); break; case Bytecodes::_aaload: array_load(T_OBJECT); break; case Bytecodes::_laload: { - a = array_addressing(T_LONG, 0, false); + a = array_addressing(T_LONG, 0); if (stopped()) return; // guaranteed null or range check dec_sp(2); // Pop array and index push_pair(make_load(control(), a, TypeLong::LONG, T_LONG, TypeAryPtr::LONGS, MemNode::unordered)); break; } case Bytecodes::_daload: { - a = array_addressing(T_DOUBLE, 0, false); + a = array_addressing(T_DOUBLE, 0); if (stopped()) return; // guaranteed null or range check dec_sp(2); // Pop array and index push_pair(make_load(control(), a, Type::DOUBLE, T_DOUBLE, TypeAryPtr::DOUBLES, MemNode::unordered)); @@ -1727,7 +1730,7 @@ case Bytecodes::_sastore: array_store(T_SHORT); break; case Bytecodes::_fastore: array_store(T_FLOAT); break; case Bytecodes::_aastore: { - d = array_addressing(T_OBJECT, 1, true); + d = array_addressing(T_OBJECT, 1); if (stopped()) return; // guaranteed null or range check array_store_check(); c = pop(); // Oop to store @@ -1735,16 +1738,11 @@ a = pop(); // the array itself const TypeOopPtr* elemtype = _gvn.type(a)->is_aryptr()->elem()->make_oopptr(); const TypeAryPtr* adr_type = TypeAryPtr::OOPS; - // Note: We don't need a write barrier for Shenandoah on a here, because - // a is not used except for an assert. The address d already has the - // write barrier. Adding a barrier on a only results in additional code - // being generated. - c = shenandoah_read_barrier_storeval(c); Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT, MemNode::release); break; } case Bytecodes::_lastore: { - a = array_addressing(T_LONG, 2, true); + a = array_addressing(T_LONG, 2); if (stopped()) return; // guaranteed null or range check c = pop_pair(); dec_sp(2); // Pop array and index @@ -1752,7 +1750,7 @@ break; } case Bytecodes::_dastore: { - a = array_addressing(T_DOUBLE, 2, true); + a = array_addressing(T_DOUBLE, 2); if (stopped()) return; // guaranteed null or range check c = pop_pair(); dec_sp(2); // Pop array and index @@ -2284,11 +2282,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - if (UseShenandoahGC && ShenandoahAcmpBarrier) { - a = shenandoah_write_barrier(a); - b = shenandoah_write_barrier(b); - } - c = _gvn.transform(new (C) CmpPNode(b, a)); + c = _gvn.transform(new (C) CmpPNode(b, a) ); c = optimize_cmp_with_klass(c); do_if(btest, c); break; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse3.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse3.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse3.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse3.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -36,6 +36,10 @@ #include "runtime/deoptimization.hpp" #include "runtime/handles.inline.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#endif + //============================================================================= // Helper methods for _get* and _put* bytecodes //============================================================================= @@ -203,16 +207,6 @@ // Compute address and memory type. int offset = field->offset_in_bytes(); const TypePtr* adr_type = C->alias_type(field)->adr_type(); - - // Insert read barrier for Shenandoah. - if ((ShenandoahOptimizeStaticFinals && field->is_static() && field->is_final()) || - (ShenandoahOptimizeInstanceFinals && !field->is_static() && field->is_final()) || - (ShenandoahOptimizeStableFinals && field->is_stable())) { - // Skip the barrier for special fields - } else { - obj = shenandoah_read_barrier(obj); - } - Node *adr = basic_plus_adr(obj, obj, offset); BasicType bt = field->layout_type(); @@ -246,16 +240,13 @@ MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered; Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, is_vol); - // Only enabled for Shenandoah. Can this be useful in general? - if (UseShenandoahGC && ShenandoahOptimizeStableFinals && UseImplicitStableValues) { - if (field->holder()->name() == ciSymbol::java_lang_String() && - field->offset() == java_lang_String::value_offset_in_bytes()) { - const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, - TypeAry::make(TypeInt::CHAR, TypeInt::POS), - ciTypeArrayKlass::make(T_CHAR), true, 0); - ld = cast_array_to_stable(ld, value_type); - } + Node* load = ld; +#if INCLUDE_ALL_GCS + if (UseShenandoahGC && (bt == T_OBJECT || bt == T_ARRAY)) { + ld = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, ld); } +#endif + // Adjust Java stack if (type2size[bt] == 1) push(ld); @@ -294,7 +285,7 @@ if (field->is_volatile()) { // Memory barrier includes bogus read of value to force load BEFORE membar assert(leading_membar == NULL || support_IRIW_for_not_multiple_copy_atomic_cpu, "no leading membar expected"); - Node* mb = insert_mem_bar(Op_MemBarAcquire, ld); + Node* mb = insert_mem_bar(Op_MemBarAcquire, load); mb->as_MemBar()->set_trailing_load(); } } @@ -309,9 +300,6 @@ leading_membar = insert_mem_bar(Op_MemBarRelease); } - // Insert write barrier for Shenandoah. - obj = shenandoah_write_barrier(obj); - // Compute address and memory type. int offset = field->offset_in_bytes(); const TypePtr* adr_type = C->alias_type(field)->adr_type(); @@ -341,9 +329,6 @@ } else { field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); } - - val = shenandoah_read_barrier_storeval(val); - store = store_oop_to_object(control(), obj, adr, adr_type, val, field_type, bt, mo); } else { store = store_to_memory(control(), adr, val, bt, adr_type, mo, is_vol); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/parse.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/parse.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -477,7 +477,7 @@ // Helper function to generate array store void array_store(BasicType etype); // Helper function to compute array addressing - Node* array_addressing(BasicType type, int vals, bool is_store, const Type* *result2=NULL); + Node* array_addressing(BasicType type, int vals, const Type* *result2=NULL); void rtm_deopt(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/phaseX.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/phaseX.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/phaseX.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/phaseX.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -35,7 +35,9 @@ #include "opto/phaseX.hpp" #include "opto/regalloc.hpp" #include "opto/rootnode.hpp" -#include "opto/shenandoahSupport.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif //============================================================================= #define NODE_HASH_MINIMUM_SIZE 255 @@ -1294,10 +1296,7 @@ i++; } assert(!(i < imax), "sanity"); - } - } else if (dead->Opcode() == Op_ShenandoahWBMemProj) { - assert(i == 0 && in->Opcode() == Op_ShenandoahWriteBarrier, "broken graph"); - _worklist.push(in); + } } else if (in->Opcode() == Op_AddP && CallLeafNode::has_only_g1_wb_pre_uses(in)) { add_users_to_worklist(in); } @@ -1347,8 +1346,8 @@ if (dead->is_expensive()) { C->remove_expensive_node(dead); } - if (dead->is_ShenandoahBarrier()) { - C->remove_shenandoah_barrier(dead->as_ShenandoahBarrier()); + if (dead->Opcode() == Op_ShenandoahLoadReferenceBarrier) { + C->remove_shenandoah_barrier(reinterpret_cast(dead)); } CastIINode* cast = dead->isa_CastII(); if (cast != NULL && cast->has_range_check()) { @@ -1564,7 +1563,7 @@ if (imem != NULL) add_users_to_worklist0(imem); } - if (use->is_ShenandoahBarrier()) { + if (use->Opcode() == Op_ShenandoahLoadReferenceBarrier) { Node* cmp = use->find_out_with(Op_CmpP); if (cmp != NULL) { _worklist.push(cmp); @@ -1694,7 +1693,7 @@ } } } - if (m->is_ShenandoahBarrier()) { + if (m->Opcode() == Op_ShenandoahLoadReferenceBarrier) { for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { Node* p = m->fast_out(i2); if (p->Opcode() == Op_CmpP) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/runtime.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/runtime.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/runtime.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/runtime.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -95,7 +95,25 @@ // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000 +// GHASH block processing +const TypeFunc* OptoRuntime::ghash_processBlocks_Type() { + int argcnt = 4; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypePtr::NOTNULL; // subkeyH + fields[argp++] = TypePtr::NOTNULL; // data + fields[argp++] = TypeInt::INT; // blocks + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = NULL; // void + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); +} // Compiled code entry points address OptoRuntime::_new_instance_Java = NULL; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/runtime.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/runtime.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/runtime.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/runtime.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -313,6 +313,8 @@ static const TypeFunc* montgomeryMultiply_Type(); static const TypeFunc* montgomerySquare_Type(); + static const TypeFunc* ghash_processBlocks_Type(); + static const TypeFunc* updateBytesCRC32_Type(); // leaf on stack replacement interpreter accessor types diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,3694 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "gc_implementation/shenandoah/shenandoahHeap.hpp" -#include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" -#include "opto/callnode.hpp" -#include "opto/connode.hpp" -#include "opto/phaseX.hpp" -#include "opto/rootnode.hpp" -#include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" -#include "opto/subnode.hpp" - -Node* ShenandoahBarrierNode::skip_through_barrier(Node* n) { - if (!UseShenandoahGC) { - return n; - } - if (n == NULL) { - return NULL; - } else if (n->is_ShenandoahBarrier()) { - return n->in(ValueIn); - } else if (n->is_Phi() && - n->req() == 3 && - n->in(1) != NULL && - n->in(1)->is_ShenandoahBarrier() && - n->in(2) != NULL && - n->in(2)->bottom_type() == TypePtr::NULL_PTR && - n->in(0) != NULL && - n->in(0)->in(1) != NULL && - n->in(0)->in(1)->is_IfProj() && - n->in(0)->in(2) != NULL && - n->in(0)->in(2)->is_IfProj() && - n->in(0)->in(1)->in(0) != NULL && - n->in(0)->in(1)->in(0) == n->in(0)->in(2)->in(0) && - n->in(1)->in(ShenandoahBarrierNode::ValueIn)->Opcode() == Op_CastPP) { - Node* iff = n->in(0)->in(1)->in(0); - Node* res = n->in(1)->in(ShenandoahBarrierNode::ValueIn)->in(1); - if (iff->is_If() && - iff->in(1) != NULL && - iff->in(1)->is_Bool() && - iff->in(1)->as_Bool()->_test._test == BoolTest::ne && - iff->in(1)->in(1) != NULL && - iff->in(1)->in(1)->Opcode() == Op_CmpP && - iff->in(1)->in(1)->in(1) != NULL && - iff->in(1)->in(1)->in(1) == res && - iff->in(1)->in(1)->in(2) != NULL && - iff->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { - return res; - } - } - return n; -} - -bool ShenandoahBarrierNode::needs_barrier(PhaseTransform* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace) { - Unique_Node_List visited; - return needs_barrier_impl(phase, orig, n, rb_mem, allow_fromspace, visited); -} - -bool ShenandoahBarrierNode::needs_barrier_impl(PhaseTransform* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace, Unique_Node_List &visited) { - - if (visited.member(n)) { - return false; // Been there. - } - visited.push(n); - - if (n->is_Allocate()) { - return false; - } - - if (n->is_Call()) { - return true; - } - - const Type* type = phase->type(n); - if (type == Type::TOP) { - return false; - } - if (type->make_ptr()->higher_equal(TypePtr::NULL_PTR)) { - return false; - } - if (type->make_oopptr() && type->make_oopptr()->const_oop() != NULL) { - return false; - } - - if (ShenandoahOptimizeStableFinals) { - const TypeAryPtr* ary = type->isa_aryptr(); - if (ary && ary->is_stable() && allow_fromspace) { - return false; - } - } - - if (n->is_CheckCastPP() || n->is_ConstraintCast()) { - return needs_barrier_impl(phase, orig, n->in(1), rb_mem, allow_fromspace, visited); - } - if (n->is_Parm()) { - return true; - } - if (n->is_Proj()) { - return needs_barrier_impl(phase, orig, n->in(0), rb_mem, allow_fromspace, visited); - } - if (n->is_Phi()) { - bool need_barrier = false; - for (uint i = 1; i < n->req() && ! need_barrier; i++) { - Node* input = n->in(i); - if (input == NULL) { - need_barrier = true; // Phi not complete yet? - } else if (needs_barrier_impl(phase, orig, input, rb_mem, allow_fromspace, visited)) { - need_barrier = true; - } - } - return need_barrier; - } - if (n->is_CMove()) { - return needs_barrier_impl(phase, orig, n->in(CMoveNode::IfFalse), rb_mem, allow_fromspace, visited) || - needs_barrier_impl(phase, orig, n->in(CMoveNode::IfTrue ), rb_mem, allow_fromspace, visited); - } - if (n->Opcode() == Op_CreateEx) { - return true; - } - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - return false; - } - if (n->Opcode() == Op_ShenandoahReadBarrier) { - if (rb_mem == n->in(Memory)) { - return false; - } else { - return true; - } - } - - if (n->Opcode() == Op_LoadP || - n->Opcode() == Op_LoadN || - n->Opcode() == Op_GetAndSetP || - n->Opcode() == Op_GetAndSetN) { - return true; - } - if (n->Opcode() == Op_DecodeN || - n->Opcode() == Op_EncodeP) { - return needs_barrier_impl(phase, orig, n->in(1), rb_mem, allow_fromspace, visited); - } - -#ifdef ASSERT - tty->print("need barrier on?: "); n->dump(); - ShouldNotReachHere(); -#endif - return true; -} - -bool ShenandoahReadBarrierNode::dominates_memory_rb_impl(PhaseTransform* phase, - Node* b1, - Node* b2, - Node* current, - bool linear) { - ResourceMark rm; - VectorSet visited(Thread::current()->resource_area()); - Node_Stack phis(0); - - for(int i = 0; i < 10; i++) { - if (current == NULL) { - return false; - } else if (visited.test_set(current->_idx) || current->is_top() || current == b1) { - current = NULL; - while (phis.is_nonempty() && current == NULL) { - uint idx = phis.index(); - Node* phi = phis.node(); - if (idx >= phi->req()) { - phis.pop(); - } else { - current = phi->in(idx); - phis.set_index(idx+1); - } - } - if (current == NULL) { - return true; - } - } else if (current == phase->C->immutable_memory()) { - return false; - } else if (current->isa_Phi()) { - if (!linear) { - return false; - } - phis.push(current, 2); - current = current->in(1); - } else if (current->Opcode() == Op_ShenandoahWriteBarrier) { - const Type* in_type = current->bottom_type(); - const Type* this_type = b2->bottom_type(); - if (is_independent(in_type, this_type)) { - current = current->in(Memory); - } else { - return false; - } - } else if (current->Opcode() == Op_ShenandoahWBMemProj) { - current = current->in(0); - } else if (current->is_Proj()) { - current = current->in(0); - } else if (current->is_Call()) { - return false; // TODO: Maybe improve by looking at the call's memory effects? - } else if (current->is_MemBar()) { - return false; // TODO: Do we need to stop at *any* membar? - } else if (current->is_MergeMem()) { - const TypePtr* adr_type = brooks_pointer_type(phase->type(b2)); - uint alias_idx = phase->C->get_alias_index(adr_type); - current = current->as_MergeMem()->memory_at(alias_idx); - } else { -#ifdef ASSERT - current->dump(); -#endif - ShouldNotReachHere(); - return false; - } - } - return false; -} - -bool ShenandoahReadBarrierNode::is_independent(Node* mem) { - if (mem->is_Phi() || mem->is_Proj() || mem->is_MergeMem()) { - return true; - } else if (mem->Opcode() == Op_ShenandoahWriteBarrier) { - const Type* mem_type = mem->bottom_type(); - const Type* this_type = bottom_type(); - if (is_independent(mem_type, this_type)) { - return true; - } else { - return false; - } - } else if (mem->is_Call() || mem->is_MemBar()) { - return false; - } -#ifdef ASSERT - mem->dump(); -#endif - ShouldNotReachHere(); - return true; -} - - -bool ShenandoahReadBarrierNode::dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2, bool linear) { - return dominates_memory_rb_impl(phase, b1->in(Memory), b2, b2->in(Memory), linear); -} - -bool ShenandoahReadBarrierNode::is_independent(const Type* in_type, const Type* this_type) { - assert(in_type->isa_oopptr(), "expect oop ptr"); - assert(this_type->isa_oopptr(), "expect oop ptr"); - - ciKlass* in_kls = in_type->is_oopptr()->klass(); - ciKlass* this_kls = this_type->is_oopptr()->klass(); - if (in_kls != NULL && this_kls != NULL && - in_kls->is_loaded() && this_kls->is_loaded() && - (!in_kls->is_subclass_of(this_kls)) && - (!this_kls->is_subclass_of(in_kls))) { - return true; - } - return false; -} - -Node* ShenandoahReadBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) { - - if (! can_reshape) { - return NULL; - } - - if (in(Memory) == phase->C->immutable_memory()) return NULL; - - // If memory input is a MergeMem, take the appropriate slice out of it. - Node* mem_in = in(Memory); - if (mem_in->isa_MergeMem()) { - const TypePtr* adr_type = brooks_pointer_type(bottom_type()); - uint alias_idx = phase->C->get_alias_index(adr_type); - mem_in = mem_in->as_MergeMem()->memory_at(alias_idx); - set_req(Memory, mem_in); - return this; - } - - Node* input = in(Memory); - if (input->Opcode() == Op_ShenandoahWBMemProj) { - Node* wb = input->in(0); - const Type* in_type = phase->type(wb); - // is_top() test not sufficient here: we can come here after CCP - // in a dead branch of the graph that has not yet been removed. - if (in_type == Type::TOP) return NULL; // Dead path. - assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "expect write barrier"); - if (is_independent(in_type, _type)) { - if (phase->is_IterGVN()) { - phase->is_IterGVN()->rehash_node_delayed(wb); - } - set_req(Memory, wb->in(Memory)); - if (can_reshape && input->outcnt() == 0) { - phase->is_IterGVN()->_worklist.push(input); - } - return this; - } - } - return NULL; -} - -Node* ShenandoahWriteBarrierNode::Identity(PhaseTransform* phase) { - assert(in(0) != NULL, "should have control"); - PhaseIterGVN* igvn = phase->is_IterGVN(); - Node* mem_in = in(Memory); - Node* mem_proj = NULL; - - if (igvn != NULL) { - mem_proj = find_out_with(Op_ShenandoahWBMemProj); - if (mem_proj == NULL || mem_in == mem_proj) { - return this; - } - } - - Node* replacement = Identity_impl(phase); - if (igvn != NULL) { - if (replacement != NULL && replacement != this) { - igvn->replace_node(mem_proj, mem_in); - } - } - return replacement; -} - - -Node* ShenandoahWriteBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) { - assert(in(0) != NULL, "should have control"); - if (!can_reshape) { - return NULL; - } - - PhaseIterGVN* igvn = phase->is_IterGVN(); - Node* mem_proj = find_out_with(Op_ShenandoahWBMemProj); - Node* mem_in = in(Memory); - - if (mem_in == phase->C->immutable_memory()) return NULL; - - if (mem_in->isa_MergeMem()) { - const TypePtr* adr_type = brooks_pointer_type(bottom_type()); - uint alias_idx = phase->C->get_alias_index(adr_type); - mem_in = mem_in->as_MergeMem()->memory_at(alias_idx); - set_req(Memory, mem_in); - return this; - } - - return NULL; -} - -bool ShenandoahBarrierNode::dominates_memory_impl(PhaseTransform* phase, - Node* b1, - Node* b2, - Node* current, - bool linear) { - ResourceMark rm; - VectorSet visited(Thread::current()->resource_area()); - Node_Stack phis(0); - - - for(int i = 0; i < 10; i++) { - if (current == NULL) { - return false; - } else if (visited.test_set(current->_idx) || current->is_top() || current == b1) { - current = NULL; - while (phis.is_nonempty() && current == NULL) { - uint idx = phis.index(); - Node* phi = phis.node(); - if (idx >= phi->req()) { - phis.pop(); - } else { - current = phi->in(idx); - phis.set_index(idx+1); - } - } - if (current == NULL) { - return true; - } - } else if (current == b2) { - return false; - } else if (current == phase->C->immutable_memory()) { - return false; - } else if (current->isa_Phi()) { - if (!linear) { - return false; - } - phis.push(current, 2); - current = current->in(1); - } else if (current->Opcode() == Op_ShenandoahWriteBarrier) { - current = current->in(Memory); - } else if (current->Opcode() == Op_ShenandoahWBMemProj) { - current = current->in(0); - } else if (current->is_Proj()) { - current = current->in(0); - } else if (current->is_Call()) { - current = current->in(TypeFunc::Memory); - } else if (current->is_MemBar()) { - current = current->in(TypeFunc::Memory); - } else if (current->is_MergeMem()) { - const TypePtr* adr_type = brooks_pointer_type(phase->type(b2)); - uint alias_idx = phase->C->get_alias_index(adr_type); - current = current->as_MergeMem()->memory_at(alias_idx); - } else { -#ifdef ASSERT - current->dump(); -#endif - ShouldNotReachHere(); - return false; - } - } - return false; -} - -/** - * Determines if b1 dominates b2 through memory inputs. It returns true if: - * - b1 can be reached by following each branch in b2's memory input (through phis, etc) - * - or we get back to b2 (i.e. through a loop) without seeing b1 - * In all other cases, (in particular, if we reach immutable_memory without having seen b1) - * we return false. - */ -bool ShenandoahBarrierNode::dominates_memory(PhaseTransform* phase, Node* b1, Node* b2, bool linear) { - return dominates_memory_impl(phase, b1, b2, b2->in(Memory), linear); -} - -Node* ShenandoahBarrierNode::Identity_impl(PhaseTransform* phase) { - Node* n = in(ValueIn); - - Node* rb_mem = Opcode() == Op_ShenandoahReadBarrier ? in(Memory) : NULL; - if (! needs_barrier(phase, this, n, rb_mem, _allow_fromspace)) { - return n; - } - - // Try to find a write barrier sibling with identical inputs that we can fold into. - for (DUIterator i = n->outs(); n->has_out(i); i++) { - Node* sibling = n->out(i); - if (sibling == this) { - continue; - } - if (sibling->Opcode() != Op_ShenandoahWriteBarrier) { - continue; - } - - assert(sibling->in(ValueIn) == in(ValueIn), "sanity"); - assert(sibling->Opcode() == Op_ShenandoahWriteBarrier, "sanity"); - - if (dominates_memory(phase, sibling, this, phase->is_IterGVN() == NULL)) { - return sibling; - } - } - return this; -} - -#ifndef PRODUCT -void ShenandoahBarrierNode::dump_spec(outputStream *st) const { - const TypePtr* adr = adr_type(); - if (adr == NULL) { - return; - } - st->print(" @"); - adr->dump_on(st); - st->print(" ("); - Compile::current()->alias_type(adr)->adr_type()->dump_on(st); - st->print(") "); -} -#endif - -Node* ShenandoahReadBarrierNode::Identity(PhaseTransform* phase) { - Node* id = Identity_impl(phase); - - if (id == this && phase->is_IterGVN()) { - Node* n = in(ValueIn); - // No success in super call. Try to combine identical read barriers. - for (DUIterator i = n->outs(); n->has_out(i); i++) { - Node* sibling = n->out(i); - if (sibling == this || sibling->Opcode() != Op_ShenandoahReadBarrier) { - continue; - } - assert(sibling->in(ValueIn) == in(ValueIn), "sanity"); - if (phase->is_IterGVN()->hash_find(sibling) && - sibling->bottom_type() == bottom_type() && - sibling->in(Control) == in(Control) && - dominates_memory_rb(phase, sibling, this, phase->is_IterGVN() == NULL)) { - return sibling; - } - } - } - return id; -} - -const Type* ShenandoahBarrierNode::Value(PhaseTransform* phase) const { - // Either input is TOP ==> the result is TOP - const Type *t1 = phase->type(in(Memory)); - if (t1 == Type::TOP) return Type::TOP; - const Type *t2 = phase->type(in(ValueIn)); - if( t2 == Type::TOP ) return Type::TOP; - - Node* input = in(ValueIn); - const Type* type = phase->type(input)->is_oopptr()->cast_to_nonconst(); - return type->filter_speculative(_type); -} - -uint ShenandoahBarrierNode::hash() const { - return TypeNode::hash() + _allow_fromspace; -} - -uint ShenandoahBarrierNode::cmp(const Node& n) const { - return _allow_fromspace == ((ShenandoahBarrierNode&) n)._allow_fromspace - && TypeNode::cmp(n); -} - -uint ShenandoahBarrierNode::size_of() const { - return sizeof(*this); -} - -Node* ShenandoahWBMemProjNode::Identity(PhaseTransform* phase) { - - Node* wb = in(0); - if (wb->is_top()) return phase->C->top(); // Dead path. - - assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "expect write barrier"); - PhaseIterGVN* igvn = phase->is_IterGVN(); - // We can't do the below unless the graph is fully constructed. - if (igvn == NULL) { - return this; - } - - // If the mem projection has no barrier users, it's not needed anymore. - Unique_Node_List visited; - if (wb->outcnt() == 1) { - return wb->in(ShenandoahBarrierNode::Memory); - } - - return this; -} - -#ifdef ASSERT -bool ShenandoahBarrierNode::verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used) { - assert(phis.size() == 0, ""); - - while (true) { - if (!in->bottom_type()->make_ptr()->isa_oopptr()) { - if (trace) {tty->print_cr("Non oop");} - } else if (t == ShenandoahLoad && ShenandoahOptimizeStableFinals && - in->bottom_type()->make_ptr()->isa_aryptr() && - in->bottom_type()->make_ptr()->is_aryptr()->is_stable()) { - if (trace) {tty->print_cr("Stable array load");} - } else { - if (in->Opcode() == Op_CastPP || in->Opcode() == Op_CheckCastPP) { - in = in->in(1); - continue; - } else if (in->is_AddP()) { - assert(!in->in(AddPNode::Address)->is_top(), "no raw memory access"); - in = in->in(AddPNode::Address); - continue; - } else if (in->is_Con()) { - if (trace) {tty->print("Found constant"); in->dump();} - } else if (in->is_ShenandoahBarrier()) { - if (t == ShenandoahStore && in->Opcode() != Op_ShenandoahWriteBarrier) { - return false; - } - barriers_used.push(in); - if (trace) {tty->print("Found barrier"); in->dump();} - } else if (in->is_Proj() && in->in(0)->is_Allocate()) { - if (trace) {tty->print("Found alloc"); in->in(0)->dump();} - } else if (in->is_Phi()) { - if (!visited.test_set(in->_idx)) { - if (trace) {tty->print("Pushed phi:"); in->dump();} - phis.push(in, 2); - in = in->in(1); - continue; - } - if (trace) {tty->print("Already seen phi:"); in->dump();} - } else if (in->Opcode() == Op_CMoveP || in->Opcode() == Op_CMoveN) { - if (!visited.test_set(in->_idx)) { - if (trace) {tty->print("Pushed cmovep:"); in->dump();} - phis.push(in, CMoveNode::IfTrue); - in = in->in(CMoveNode::IfFalse); - continue; - } - if (trace) {tty->print("Already seen cmovep:"); in->dump();} - } else if (in->Opcode() == Op_EncodeP || in->Opcode() == Op_DecodeN) { - in = in->in(1); - continue; - } else { - return false; - } - } - bool cont = false; - while (phis.is_nonempty()) { - uint idx = phis.index(); - Node* phi = phis.node(); - if (idx >= phi->req()) { - if (trace) {tty->print("Popped phi:"); phi->dump();} - phis.pop(); - continue; - } - if (trace) {tty->print("Next entry(%d) for phi:", idx); phi->dump();} - in = phi->in(idx); - phis.set_index(idx+1); - cont = true; - break; - } - if (!cont) { - break; - } - } - return true; -} - -void ShenandoahBarrierNode::report_verify_failure(const char *msg, Node *n1, Node *n2) { - if (n1 != NULL) { - n1->dump(+10); - } - if (n2 != NULL) { - n2->dump(+10); - } - fatal(msg); -} - -void ShenandoahBarrierNode::verify(RootNode* root) { - ResourceMark rm; - Unique_Node_List wq; - GrowableArray barriers; - Unique_Node_List barriers_used; - Node_Stack phis(0); - VectorSet visited(Thread::current()->resource_area()); - const bool trace = false; - const bool verify_no_useless_barrier = false; - - wq.push(root); - for (uint next = 0; next < wq.size(); next++) { - Node *n = wq.at(next); - if (n->is_Load()) { - const bool trace = false; - if (trace) {tty->print("Verifying"); n->dump();} - if (n->Opcode() == Op_LoadRange || n->Opcode() == Op_LoadKlass || n->Opcode() == Op_LoadNKlass) { - if (trace) {tty->print_cr("Load range/klass");} - } else { - const TypePtr* adr_type = n->as_Load()->adr_type(); - - if (adr_type->isa_oopptr() && adr_type->is_oopptr()->offset() == oopDesc::mark_offset_in_bytes()) { - if (trace) {tty->print_cr("Mark load");} - } else if (adr_type->isa_instptr() && - adr_type->is_instptr()->klass()->is_subtype_of(Compile::current()->env()->Reference_klass()) && - adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset) { - if (trace) {tty->print_cr("Reference.get()");} - } else { - bool verify = true; - if (adr_type->isa_instptr()) { - ciKlass* k = adr_type->is_instptr()->klass(); - assert(k->is_instance_klass(), ""); - ciInstanceKlass* ik = (ciInstanceKlass*)k; - int offset = adr_type->offset(); - - if ((ik->debug_final_field_at(offset) && ShenandoahOptimizeInstanceFinals) || - (ik->debug_stable_field_at(offset) && ShenandoahOptimizeStableFinals)) { - if (trace) {tty->print_cr("Final/stable");} - verify = false; - } - } - - if (verify && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahLoad, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: Load should have barriers", n); - } - } - } - } else if (n->is_Store()) { - const bool trace = false; - - if (trace) {tty->print("Verifying"); n->dump();} - if (n->in(MemNode::ValueIn)->bottom_type()->isa_oopptr()) { - Node* adr = n->in(MemNode::Address); - bool verify = true; - - if (adr->is_AddP() && adr->in(AddPNode::Base)->is_top()) { - adr = adr->in(AddPNode::Address); - if (adr->is_AddP()) { - assert(adr->in(AddPNode::Base)->is_top(), ""); - adr = adr->in(AddPNode::Address); - if (adr->Opcode() == Op_LoadP && - adr->in(MemNode::Address)->in(AddPNode::Base)->is_top() && - adr->in(MemNode::Address)->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && - adr->in(MemNode::Address)->in(AddPNode::Offset)->find_intptr_t_con(-1) == in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf())) { - if (trace) {tty->print_cr("G1 prebarrier");} - verify = false; - } - } - } - - if (verify && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahValue, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: Store should have barriers", n); - } - } - if (!ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: Store (address) should have barriers", n); - } - } else if (n->is_ClearArray()) { - if (!ShenandoahBarrierNode::verify_helper(n->in(3), phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: ClearArray should have barriers", n); - } - } else if (n->Opcode() == Op_CmpP) { - const bool trace = false; - - Node* in1 = n->in(1); - Node* in2 = n->in(2); - if (in1->bottom_type()->isa_oopptr()) { - if (trace) {tty->print("Verifying"); n->dump();} - - bool mark_inputs = false; - if (in1->is_Con() || in2->is_Con()) { - if (trace) {tty->print_cr("Comparison against a constant");} - mark_inputs = true; - } else if ((in1->is_CheckCastPP() && in1->in(1)->is_Proj() && in1->in(1)->in(0)->is_Allocate()) || - (in2->is_CheckCastPP() && in2->in(1)->is_Proj() && in2->in(1)->in(0)->is_Allocate())) { - if (trace) {tty->print_cr("Comparison with newly alloc'ed object");} - mark_inputs = true; - } else { - assert(in2->bottom_type()->isa_oopptr(), ""); - - if (!ShenandoahBarrierNode::verify_helper(in1, phis, visited, ShenandoahStore, trace, barriers_used) || - !ShenandoahBarrierNode::verify_helper(in2, phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: Cmp should have barriers", n); - } - } - if (verify_no_useless_barrier && - mark_inputs && - (!ShenandoahBarrierNode::verify_helper(in1, phis, visited, ShenandoahValue, trace, barriers_used) || - !ShenandoahBarrierNode::verify_helper(in2, phis, visited, ShenandoahValue, trace, barriers_used))) { - phis.clear(); - visited.Reset(); - } - } - } else if (n->is_LoadStore()) { - if (n->in(MemNode::ValueIn)->bottom_type()->make_ptr() && - !ShenandoahBarrierNode::verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahValue, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: LoadStore (value) should have barriers", n); - } - - if (n->in(MemNode::Address)->bottom_type()->make_oopptr() && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: LoadStore (address) should have barriers", n); - } - } else if (n->Opcode() == Op_CallLeafNoFP || n->Opcode() == Op_CallLeaf) { - CallRuntimeNode* call = n->as_CallRuntime(); - - static struct { - const char* name; - struct { - int pos; - verify_type t; - } args[6]; - } calls[] = { - "aescrypt_encryptBlock", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "aescrypt_decryptBlock", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "multiplyToLen", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { TypeFunc::Parms+4, ShenandoahStore }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "squareToLen", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "montgomery_multiply", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, - { TypeFunc::Parms+6, ShenandoahStore }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "montgomery_square", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+5, ShenandoahStore }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "mulAdd", - { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "vectorizedMismatch", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "updateBytesCRC32", - { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "updateBytesAdler32", - { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "updateBytesCRC32C", - { { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahLoad}, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "counterMode_AESCrypt", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, - { TypeFunc::Parms+3, ShenandoahStore }, { TypeFunc::Parms+5, ShenandoahStore }, { TypeFunc::Parms+6, ShenandoahStore } }, - "cipherBlockChaining_encryptAESCrypt", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, - { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "cipherBlockChaining_decryptAESCrypt", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, - { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "shenandoah_clone_barrier", - { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "ghash_processBlocks", - { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha1_implCompress", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha256_implCompress", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha512_implCompress", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha1_implCompressMB", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha256_implCompressMB", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - "sha512_implCompressMB", - { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, - { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, - }; - - if (call->is_call_to_arraycopystub()) { - Node* dest = NULL; - const TypeTuple* args = n->as_Call()->_tf->domain(); - for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) { - if (args->field_at(i)->isa_ptr()) { - j++; - if (j == 2) { - dest = n->in(i); - break; - } - } - } - if (!ShenandoahBarrierNode::verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahLoad, trace, barriers_used) || - !ShenandoahBarrierNode::verify_helper(dest, phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: ArrayCopy should have barriers", n); - } - } else if (strlen(call->_name) > 5 && - !strcmp(call->_name + strlen(call->_name) - 5, "_fill")) { - if (!ShenandoahBarrierNode::verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahStore, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: _fill should have barriers", n); - } - } else if (!strcmp(call->_name, "g1_wb_pre")) { - // skip - } else { - const int calls_len = sizeof(calls) / sizeof(calls[0]); - int i = 0; - for (; i < calls_len; i++) { - if (!strcmp(calls[i].name, call->_name)) { - break; - } - } - if (i != calls_len) { - const uint args_len = sizeof(calls[0].args) / sizeof(calls[0].args[0]); - for (uint j = 0; j < args_len; j++) { - int pos = calls[i].args[j].pos; - if (pos == -1) { - break; - } - if (!ShenandoahBarrierNode::verify_helper(call->in(pos), phis, visited, calls[i].args[j].t, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); - } - } - for (uint j = TypeFunc::Parms; j < call->req(); j++) { - if (call->in(j)->bottom_type()->make_ptr() && - call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { - uint k = 0; - for (; k < args_len && calls[i].args[k].pos != (int)j; k++); - if (k == args_len) { - fatal(err_msg("arg %d for call %s not covered", j, call->_name)); - } - } - } - } else { - for (uint j = TypeFunc::Parms; j < call->req(); j++) { - if (call->in(j)->bottom_type()->make_ptr() && - call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { - fatal(err_msg("%s not covered", call->_name)); - } - } - } - } - } else if (n->is_ShenandoahBarrier()) { - assert(!barriers.contains(n), ""); - assert(n->Opcode() != Op_ShenandoahWriteBarrier || n->find_out_with(Op_ShenandoahWBMemProj) != NULL, "bad shenandoah write barrier"); - assert(n->Opcode() != Op_ShenandoahWriteBarrier || n->outcnt() > 1, "bad shenandoah write barrier"); - barriers.push(n); - } else if (n->is_AddP() - || n->is_Phi() - || n->Opcode() == Op_CastPP - || n->Opcode() == Op_CheckCastPP - || n->Opcode() == Op_Return - || n->Opcode() == Op_CMoveP - || n->Opcode() == Op_CMoveN - || n->Opcode() == Op_Rethrow - || n->is_MemBar() - || n->Opcode() == Op_Conv2B - || n->Opcode() == Op_SafePoint - || n->is_CallJava() - || n->Opcode() == Op_Unlock - || n->Opcode() == Op_EncodeP - || n->Opcode() == Op_DecodeN) { - // nothing to do - } else { - static struct { - int opcode; - struct { - int pos; - verify_type t; - } inputs[2]; - } others[] = { - Op_FastLock, - { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, - Op_Lock, - { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone} }, - Op_AryEq, - { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, - Op_StrIndexOf, - { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, - Op_StrComp, - { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, - Op_StrEquals, - { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, - Op_EncodeISOArray, - { { 2, ShenandoahLoad }, { 3, ShenandoahStore } }, - Op_CastP2X, - { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, - }; - - const int others_len = sizeof(others) / sizeof(others[0]); - int i = 0; - for (; i < others_len; i++) { - if (others[i].opcode == n->Opcode()) { - break; - } - } - uint stop = n->is_Call() ? n->as_Call()->tf()->domain()->cnt() : n->req(); - if (i != others_len) { - const uint inputs_len = sizeof(others[0].inputs) / sizeof(others[0].inputs[0]); - for (uint j = 0; j < inputs_len; j++) { - int pos = others[i].inputs[j].pos; - if (pos == -1) { - break; - } - if (!ShenandoahBarrierNode::verify_helper(n->in(pos), phis, visited, others[i].inputs[j].t, trace, barriers_used)) { - report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); - } - } - for (uint j = 1; j < stop; j++) { - if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && - n->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { - uint k = 0; - for (; k < inputs_len && others[i].inputs[k].pos != (int)j; k++); - if (k == inputs_len) { - fatal(err_msg("arg %d for node %s not covered", j, n->Name())); - } - } - } - } else { - for (uint j = 1; j < stop; j++) { - if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && - n->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { - fatal(err_msg("%s not covered", n->Name())); - } - } - } - } - - if (n->is_SafePoint()) { - SafePointNode* sfpt = n->as_SafePoint(); - if (verify_no_useless_barrier && sfpt->jvms() != NULL) { - for (uint i = sfpt->jvms()->scloff(); i < sfpt->jvms()->endoff(); i++) { - if (!ShenandoahBarrierNode::verify_helper(sfpt->in(i), phis, visited, ShenandoahLoad, trace, barriers_used)) { - phis.clear(); - visited.Reset(); - } - } - } - } - for( uint i = 0; i < n->len(); ++i ) { - Node *m = n->in(i); - if (m == NULL) continue; - - // In most cases, inputs should be known to be non null. If it's - // not the case, it could be a missing cast_not_null() in an - // intrinsic or support might be needed in AddPNode::Ideal() to - // avoid a NULL+offset input. - if (!(n->is_Phi() || - (n->is_SafePoint() && (!n->is_CallRuntime() || !strcmp(n->as_CallRuntime()->_name, "g1_wb_pre") || !strcmp(n->as_CallRuntime()->_name, "unsafe_arraycopy"))) || - n->Opcode() == Op_CmpP || - n->Opcode() == Op_CmpN || - (n->Opcode() == Op_StoreP && i == StoreNode::ValueIn) || - (n->Opcode() == Op_StoreN && i == StoreNode::ValueIn) || - n->Opcode() == Op_CheckCastPP || - n->Opcode() == Op_CastPP || - n->Opcode() == Op_Return || - n->Opcode() == Op_Conv2B || - n->is_AddP() || - n->Opcode() == Op_CMoveP || - n->Opcode() == Op_CMoveN || - n->Opcode() == Op_Rethrow || - n->is_MemBar() || - n->is_Mem() || - n->Opcode() == Op_AryEq || - n->Opcode() == Op_SCMemProj || - n->Opcode() == Op_EncodeP || - n->Opcode() == Op_DecodeN || - (n->is_CallRuntime() && !strcmp(n->as_CallRuntime()->_name, "generic_arraycopy")))) { - if (m->bottom_type()->isa_oopptr() && m->bottom_type()->meet(TypePtr::NULL_PTR) == m->bottom_type()) { - report_verify_failure("Shenandoah verification: null input", n, m); - } - } - - wq.push(m); - } - } - - if (verify_no_useless_barrier) { - for (int i = 0; i < barriers.length(); i++) { - Node* n = barriers.at(i); - if (!barriers_used.member(n)) { - tty->print("XXX useless barrier"); n->dump(-2); - ShouldNotReachHere(); - } - } - } -} -#endif - -MergeMemNode* ShenandoahWriteBarrierNode::allocate_merge_mem(Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, PhaseIdealLoop* phase) { - MergeMemNode* mm = MergeMemNode::make(phase->C, mem); - mm->set_memory_at(alias, rep_proj); - phase->register_new_node(mm, rep_ctrl); - return mm; -} - -MergeMemNode* ShenandoahWriteBarrierNode::clone_merge_mem(Node* u, Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, DUIterator& i, PhaseIdealLoop* phase) { - MergeMemNode* newmm = NULL; - MergeMemNode* u_mm = u->as_MergeMem(); - Node* c = phase->get_ctrl(u); - if (phase->is_dominator(c, rep_ctrl)) { - c = rep_ctrl; - } else { - assert(phase->is_dominator(rep_ctrl, c), "one must dominate the other"); - } - if (u->outcnt() == 1) { - if (u->req() > (uint)alias && u->in(alias) == mem) { - phase->igvn().replace_input_of(u, alias, rep_proj); - --i; - } else { - phase->igvn().rehash_node_delayed(u); - u_mm->set_memory_at(alias, rep_proj); - } - newmm = u_mm; - phase->set_ctrl_and_loop(u, c); - } else { - // can't simply clone u and then change one of its input because - // it adds and then removes an edge which messes with the - // DUIterator - newmm = MergeMemNode::make(phase->C, u_mm->base_memory()); - for (uint j = 0; j < u->req(); j++) { - if (j < newmm->req()) { - if (j == (uint)alias) { - newmm->set_req(j, rep_proj); - } else if (newmm->in(j) != u->in(j)) { - newmm->set_req(j, u->in(j)); - } - } else if (j == (uint)alias) { - newmm->add_req(rep_proj); - } else { - newmm->add_req(u->in(j)); - } - } - if ((uint)alias >= u->req()) { - newmm->set_memory_at(alias, rep_proj); - } - phase->register_new_node(newmm, c); - } - return newmm; -} - -bool ShenandoahWriteBarrierNode::should_process_phi(Node* phi, int alias, Compile* C) { - if (phi->adr_type() == TypePtr::BOTTOM) { - Node* region = phi->in(0); - for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax; j++) { - Node* uu = region->fast_out(j); - if (uu->is_Phi() && uu != phi && uu->bottom_type() == Type::MEMORY && C->get_alias_index(uu->adr_type()) == alias) { - return false; - } - } - return true; - } - return C->get_alias_index(phi->adr_type()) == alias; -} - -bool ShenandoahBarrierNode::is_dominator_same_ctrl(Node*c, Node* d, Node* n, PhaseIdealLoop* phase) { - // That both nodes have the same control is not sufficient to prove - // domination, verify that there's no path from d to n - ResourceMark rm; - Unique_Node_List wq; - wq.push(d); - for (uint next = 0; next < wq.size(); next++) { - Node *m = wq.at(next); - if (m == n) { - return false; - } - if (m->is_Phi() && m->in(0)->is_Loop()) { - assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control"); - } else { - for (uint i = 0; i < m->req(); i++) { - if (m->in(i) != NULL && phase->ctrl_or_self(m->in(i)) == c) { - wq.push(m->in(i)); - } - } - } - } - return true; -} - -bool ShenandoahBarrierNode::is_dominator(Node *d_c, Node *n_c, Node* d, Node* n, PhaseIdealLoop* phase) { - if (d_c != n_c) { - return phase->is_dominator(d_c, n_c); - } - return is_dominator_same_ctrl(d_c, d, n, phase); -} - -Node* next_mem(Node* mem, int alias) { - Node* res = NULL; - if (mem->is_Proj()) { - res = mem->in(0); - } else if (mem->is_SafePoint() || mem->is_MemBar()) { - res = mem->in(TypeFunc::Memory); - } else if (mem->is_Phi()) { - res = mem->in(1); - } else if (mem->is_ShenandoahBarrier()) { - res = mem->in(ShenandoahBarrierNode::Memory); - } else if (mem->is_MergeMem()) { - res = mem->as_MergeMem()->memory_at(alias); - } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { - assert(alias = Compile::AliasIdxRaw, "following raw memory can't lead to a barrier"); - res = mem->in(MemNode::Memory); - } else { -#ifdef ASSERT - mem->dump(); -#endif - ShouldNotReachHere(); - } - return res; -} - -bool shenandoah_suitable_mem(Node* mem, Node* old_mem, Node* rep_proj) { - for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { - Node* u = mem->fast_out(i); - if (u->is_MergeMem()) { - if (u->has_out_with(Op_MergeMem)) { - // too complicated for now - return false; - } - if (old_mem == u && rep_proj->has_out_with(Op_MergeMem)) { - return false; - } - } - if (u->Opcode() == Op_Unlock && mem->is_Proj() && mem->in(0)->Opcode() == Op_MemBarReleaseLock) { - // would require a merge mem between unlock and the - // preceding membar. Would confuse logic that eliminates - // lock/unlock nodes. - return false; - } - } - return true; -} - -void ShenandoahWriteBarrierNode::fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl, int alias, PhaseIdealLoop* phase) { - uint last =phase-> C->unique(); - MergeMemNode* mm = NULL; - assert(mem->bottom_type() == Type::MEMORY, ""); - for (DUIterator i = mem->outs(); mem->has_out(i); i++) { - Node* u = mem->out(i); - if (u != replacement && u->_idx < last) { - if (u->is_ShenandoahBarrier() && alias != Compile::AliasIdxRaw) { - if (phase->C->get_alias_index(u->adr_type()) == alias && is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { - phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); - assert(u->find_edge(mem) == -1, "only one edge"); - --i; - } - } else if (u->is_Mem()) { - if (phase->C->get_alias_index(u->adr_type()) == alias && is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { - assert(alias == Compile::AliasIdxRaw , "only raw memory can lead to a memory operation"); - phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); - assert(u->find_edge(mem) == -1, "only one edge"); - --i; - } - } else if (u->is_MergeMem()) { - MergeMemNode* u_mm = u->as_MergeMem(); - if (u_mm->memory_at(alias) == mem) { - MergeMemNode* newmm = NULL; - for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { - Node* uu = u->fast_out(j); - assert(!uu->is_MergeMem(), "chain of MergeMems?"); - if (uu->is_Phi()) { - if (should_process_phi(uu, alias, phase->C)) { - Node* region = uu->in(0); - int nb = 0; - for (uint k = 1; k < uu->req(); k++) { - if (uu->in(k) == u && phase->is_dominator(rep_ctrl, region->in(k))) { - if (newmm == NULL) { - newmm = clone_merge_mem(u, mem, alias, rep_proj, rep_ctrl, i, phase); - } - if (newmm != u) { - phase->igvn().replace_input_of(uu, k, newmm); - nb++; - --jmax; - } - } - } - if (nb > 0) { - --j; - } - } - } else { - if (rep_ctrl != uu && is_dominator(rep_ctrl, phase->ctrl_or_self(uu), replacement, uu, phase)) { - if (newmm == NULL) { - newmm = clone_merge_mem(u, mem, alias, rep_proj, rep_ctrl, i, phase); - } - if (newmm != u) { - phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); - --j, --jmax; - } - } - } - } - } - } else if (u->is_Phi()) { - assert(u->bottom_type() == Type::MEMORY, "what else?"); - Node* region = u->in(0); - if (should_process_phi(u, alias, phase->C)) { - bool replaced = false; - for (uint j = 1; j < u->req(); j++) { - if (u->in(j) == mem && phase->is_dominator(rep_ctrl, region->in(j))) { - Node* nnew = rep_proj; - if (u->adr_type() == TypePtr::BOTTOM) { - if (mm == NULL) { - mm = allocate_merge_mem(mem, alias, rep_proj, rep_ctrl, phase); - } - nnew = mm; - } - phase->igvn().replace_input_of(u, j, nnew); - replaced = true; - } - } - if (replaced) { - --i; - } - - } - } else if (u->adr_type() == TypePtr::BOTTOM || u->adr_type() == NULL) { - assert(u->adr_type() != NULL || - u->Opcode() == Op_Rethrow || - u->Opcode() == Op_Return || - u->Opcode() == Op_SafePoint || - (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || - (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || - u->Opcode() == Op_CallLeaf, ""); - if (is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { - if (mm == NULL) { - mm = allocate_merge_mem(mem, alias, rep_proj, rep_ctrl, phase); - } - phase->igvn().replace_input_of(u, u->find_edge(mem), mm); - --i; - } - } else if (phase->C->get_alias_index(u->adr_type()) == alias) { - if (is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { - phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); - --i; - } - } - } - } -} - -Node* PhaseIdealLoop::shenandoah_no_branches(Node* c, Node* dom, bool allow_one_proj) { - Node* iffproj = NULL; - while (c != dom) { - Node* next = idom(c); - assert(next->unique_ctrl_out() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?"); - if (c->is_Region()) { - ResourceMark rm; - Unique_Node_List wq; - wq.push(c); - for (uint i = 0; i < wq.size(); i++) { - Node *n = wq.at(i); - if (n->is_Region()) { - for (uint j = 1; j < n->req(); j++) { - if (n->in(j) != next) { - wq.push(n->in(j)); - } - } - } else { - if (n->in(0) != next) { - wq.push(n->in(0)); - } - } - } - for (DUIterator_Fast imax, i = next->fast_outs(imax); i < imax; i++) { - Node* u = next->fast_out(i); - if (u->is_CFG()) { - if (!wq.member(u)) { - return NodeSentinel; - } - } - } - - } else if (c->is_Proj()) { - if (c->is_IfProj()) { - if (c->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) != NULL) { - // continue; - } else { - if (!allow_one_proj) { - return NodeSentinel; - } - if (iffproj == NULL) { - iffproj = c; - } else { - return NodeSentinel; - } - } - } else if (c->Opcode() == Op_JumpProj) { - return NodeSentinel; // unsupported - } else if (c->Opcode() == Op_CatchProj) { - return NodeSentinel; // unsupported - } else if (c->Opcode() == Op_CProj && next->Opcode() == Op_NeverBranch) { - return NodeSentinel; // unsupported - } else { - assert(next->unique_ctrl_out() == c, "unsupported branch pattern"); - } - } - c = next; - } - return iffproj; -} - -#ifdef ASSERT -void PhaseIdealLoop::shenandoah_memory_dominates_all_paths_helper(Node* c, Node* rep_ctrl, Unique_Node_List& controls) { - const bool trace = false; - if (trace) { tty->print("X control is"); c->dump(); } - - uint start = controls.size(); - controls.push(c); - for (uint i = start; i < controls.size(); i++) { - Node *n = controls.at(i); - - if (trace) { tty->print("X from"); n->dump(); } - - if (n == rep_ctrl) { - continue; - } - - if (n->is_Proj()) { - Node* n_dom = n->in(0); - IdealLoopTree* n_dom_loop = get_loop(n_dom); - if (n->is_IfProj() && n_dom->outcnt() == 2) { - n_dom_loop = get_loop(n_dom->as_If()->proj_out(n->as_Proj()->_con == 0 ? 1 : 0)); - } - if (n_dom_loop != _ltree_root) { - Node* tail = n_dom_loop->tail(); - if (tail->is_Region()) { - for (uint j = 1; j < tail->req(); j++) { - if (is_dominator(n_dom, tail->in(j)) && !is_dominator(n, tail->in(j))) { - assert(is_dominator(rep_ctrl, tail->in(j)), "why are we here?"); - // entering loop from below, mark backedge - if (trace) { tty->print("X pushing backedge"); tail->in(j)->dump(); } - controls.push(tail->in(j)); - //assert(n->in(0) == n_dom, "strange flow control"); - } - } - } else if (get_loop(n) != n_dom_loop && is_dominator(n_dom, tail)) { - // entering loop from below, mark backedge - if (trace) { tty->print("X pushing backedge"); tail->dump(); } - controls.push(tail); - //assert(n->in(0) == n_dom, "strange flow control"); - } - } - } - - if (n->is_Loop()) { - Node* c = n->in(LoopNode::EntryControl); - if (trace) { tty->print("X pushing"); c->dump(); } - controls.push(c); - } else if (n->is_Region()) { - for (uint i = 1; i < n->req(); i++) { - Node* c = n->in(i); - if (trace) { tty->print("X pushing"); c->dump(); } - controls.push(c); - } - } else { - Node* c = n->in(0); - if (trace) { tty->print("X pushing"); c->dump(); } - controls.push(c); - } - } -} - -bool PhaseIdealLoop::shenandoah_memory_dominates_all_paths(Node* mem, Node* rep_ctrl, int alias) { - const bool trace = false; - if (trace) { - tty->print("XXX mem is"); mem->dump(); - tty->print("XXX rep ctrl is"); rep_ctrl->dump(); - tty->print_cr("XXX alias is %d", alias); - } - ResourceMark rm; - Unique_Node_List wq; - Unique_Node_List controls; - wq.push(mem); - for (uint next = 0; next < wq.size(); next++) { - Node *nn = wq.at(next); - if (trace) { tty->print("XX from mem"); nn->dump(); } - assert(nn->bottom_type() == Type::MEMORY, "memory only"); - - if (nn->is_Phi()) { - Node* r = nn->in(0); - for (DUIterator_Fast jmax, j = r->fast_outs(jmax); j < jmax; j++) { - Node* u = r->fast_out(j); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY && u != nn && - (u->adr_type() == TypePtr::BOTTOM || C->get_alias_index(u->adr_type()) == alias)) { - if (trace) { tty->print("XX Next mem (other phi)"); u->dump(); } - wq.push(u); - } - } - } - - for (DUIterator_Fast imax, i = nn->fast_outs(imax); i < imax; i++) { - Node* use = nn->fast_out(i); - - if (trace) { tty->print("XX use %p", use->adr_type()); use->dump(); } - if (use->is_CFG()) { - assert(use->in(TypeFunc::Memory) == nn, "bad cfg node"); - Node* c = use->in(0); - if (is_dominator(rep_ctrl, c)) { - shenandoah_memory_dominates_all_paths_helper(c, rep_ctrl, controls); - } else if (use->is_CallStaticJava() && use->as_CallStaticJava()->uncommon_trap_request() != 0 && c->is_Region()) { - Node* region = c; - if (trace) { tty->print("XX unc region"); region->dump(); } - for (uint j = 1; j < region->req(); j++) { - if (is_dominator(rep_ctrl, region->in(j))) { - if (trace) { tty->print("XX unc follows"); region->in(j)->dump(); } - shenandoah_memory_dominates_all_paths_helper(region->in(j), rep_ctrl, controls); - } - } - } - //continue; - } else if (use->is_Phi()) { - assert(use->bottom_type() == Type::MEMORY, "bad phi"); - if ((use->adr_type() == TypePtr::BOTTOM /*&& !shenandoah_has_alias_phi(C, use, alias)*/) || - C->get_alias_index(use->adr_type()) == alias) { - for (uint j = 1; j < use->req(); j++) { - if (use->in(j) == nn) { - Node* c = use->in(0)->in(j); - if (is_dominator(rep_ctrl, c)) { - shenandoah_memory_dominates_all_paths_helper(c, rep_ctrl, controls); - } - } - } - } - // continue; - } - - if (use->is_MergeMem()) { - if (use->as_MergeMem()->memory_at(alias) == nn) { - if (trace) { tty->print("XX Next mem"); use->dump(); } - // follow the memory edges - wq.push(use); - } - } else if (use->is_Phi()) { - assert(use->bottom_type() == Type::MEMORY, "bad phi"); - if ((use->adr_type() == TypePtr::BOTTOM /*&& !shenandoah_has_alias_phi(C, use, alias)*/) || - C->get_alias_index(use->adr_type()) == alias) { - if (trace) { tty->print("XX Next mem"); use->dump(); } - // follow the memory edges - wq.push(use); - } - } else if (use->bottom_type() == Type::MEMORY && - (use->adr_type() == TypePtr::BOTTOM || C->get_alias_index(use->adr_type()) == alias)) { - if (trace) { tty->print("XX Next mem"); use->dump(); } - // follow the memory edges - wq.push(use); - } else if ((use->is_SafePoint() || use->is_MemBar()) && - (use->adr_type() == TypePtr::BOTTOM || C->get_alias_index(use->adr_type()) == alias)) { - for (DUIterator_Fast jmax, j = use->fast_outs(jmax); j < jmax; j++) { - Node* u = use->fast_out(j); - if (u->bottom_type() == Type::MEMORY) { - if (trace) { tty->print("XX Next mem"); u->dump(); } - // follow the memory edges - wq.push(u); - } - } - } else if (use->Opcode() == Op_ShenandoahWriteBarrier && C->get_alias_index(use->adr_type()) == alias) { - Node* m = use->find_out_with(Op_ShenandoahWBMemProj); - if (m != NULL) { - if (trace) { tty->print("XX Next mem"); m->dump(); } - // follow the memory edges - wq.push(m); - } - } - } - } - - if (controls.size() == 0) { - return false; - } - - for (uint i = 0; i < controls.size(); i++) { - Node *n = controls.at(i); - - if (trace) { tty->print("X checking"); n->dump(); } - - if (n->unique_ctrl_out() != NULL) { - continue; - } - - if (n->Opcode() == Op_NeverBranch) { - Node* taken = n->as_Multi()->proj_out(0); - if (!controls.member(taken)) { - if (trace) { tty->print("X not seen"); taken->dump(); } - return false; - } - continue; - } - - for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { - Node* u = n->fast_out(j); - - if (u->is_CFG()) { - if (!controls.member(u)) { - if (u->is_Proj() && u->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) { - if (trace) { tty->print("X not seen but unc"); u->dump(); } - } else if (u->unique_ctrl_out() != NULL && u->unique_ctrl_out()->Opcode() == Op_Halt) { - if (trace) { tty->print("X not seen but halt"); u->dump(); } - } else { - Node* c = u; - do { - c = c->unique_ctrl_out(); - } while (c != NULL && c->is_Region()); - if (c != NULL && c->Opcode() == Op_Halt) { - if (trace) { tty->print("X not seen but halt"); c->dump(); } - } else { - if (trace) { tty->print("X not seen"); u->dump(); } - return false; - } - } - } else { - if (trace) { tty->print("X seen"); u->dump(); } - } - } - } - } - return true; -} -#endif - -static bool has_mem_phi(Compile* C, Node* region, int alias) { - for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { - Node* use = region->fast_out(i); - if (use->is_Phi() && use->bottom_type() == Type::MEMORY && - (C->get_alias_index(use->adr_type()) == alias)) { - return true; - } - } - return false; -} - -bool PhaseIdealLoop::shenandoah_fix_mem_phis_helper(Node* c, Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias, VectorSet& controls, GrowableArray& regions) { - const bool trace = false; - Node_List wq; - wq.push(c); - -#ifdef ASSERT - if (trace) { tty->print("YYY from"); c->dump(); } - if (trace) { tty->print("YYY with mem"); mem->dump(); } -#endif - - while(wq.size() > 0) { - c = wq.pop(); - - while (!c->is_Region() || c->is_Loop()) { -#ifdef ASSERT - if (trace) { tty->print("YYY"); c->dump(); } -#endif - assert(c->is_CFG(), "node should be control node"); - if (c == mem_ctrl || is_dominator(c, rep_ctrl)) { - c = NULL; - break; - } else if (c->is_Loop()) { - c = c->in(LoopNode::EntryControl); - } else { - c = c->in(0); - } - } - if (c == NULL) { - continue; - } - -#ifdef ASSERT - if (trace) { tty->print("YYY new region"); c->dump(); } -#endif - - bool has_phi = has_mem_phi(C, c, alias); - if (!has_phi) { - - Node* m = mem; - Node* m_ctrl = ctrl_or_self(m); - { - ResourceMark rm; - VectorSet wq(Thread::current()->resource_area()); - wq.set(m->_idx); - while (!is_dominator(m_ctrl, c) || m_ctrl == c) { - m = next_mem(m, alias); - if (wq.test_set(m->_idx)) { - return false; - } - m_ctrl = ctrl_or_self(m); - } - } - - assert(m->bottom_type() == Type::MEMORY, ""); - - if (m->is_MergeMem()) { - m = m->as_MergeMem()->memory_at(alias); - m_ctrl = ctrl_or_self(m); - } - -#ifdef ASSERT - if (trace) { tty->print("YYY mem "); m->dump(); } -#endif - - if (controls.test(c->_idx)) { - int i; - for (i = 0; i < regions.length() && regions.at(i) != c; i+=2) { - // deliberately empty, rolling over the regions - } - assert(i < regions.length(), "missing region"); - Node* prev_m = regions.at(i+1); - if (prev_m == m) { - continue; - } -#ifdef ASSERT - if (trace) { tty->print("YYY prev mem "); prev_m->dump(); } -#endif - Node* prev_m_ctrl = ctrl_or_self(prev_m); - assert(ShenandoahBarrierNode::is_dominator(m_ctrl, prev_m_ctrl, m, prev_m, this) || - ShenandoahBarrierNode::is_dominator(prev_m_ctrl, m_ctrl, prev_m, m, this), "one should dominate the other"); - if (ShenandoahBarrierNode::is_dominator(m_ctrl, prev_m_ctrl, m, prev_m, this)) { - continue; - } -#ifdef ASSERT - if (trace) { tty->print("YYY Fixing "); c->dump(); } -#endif - regions.at_put(i+1, m); - } else { -#ifdef ASSERT - if (trace) { tty->print("YYY Pushing "); c->dump(); } -#endif - regions.push(c); - regions.push(m); - } - } else { - continue; - } - - controls.set(c->_idx); - - for (uint i = 1; i < c->req(); i++) { - wq.push(c->in(i)); - } - } - return true; -} - - -bool PhaseIdealLoop::shenandoah_fix_mem_phis(Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias) { - GrowableArray regions; - VectorSet controls(Thread::current()->resource_area()); - const bool trace = false; - -#ifdef ASSERT - if (trace) { tty->print("YYY mem is "); mem->dump(); } - if (trace) { tty->print("YYY mem ctrl is "); mem_ctrl->dump(); } - if (trace) { tty->print("YYY rep ctrl is "); rep_ctrl->dump(); } - if (trace) { tty->print_cr("YYY alias is %d", alias); } -#endif - - // Walk memory edges from mem until we hit a memory point where - // control is known then follow the control up looking for regions - // with no memory Phi for alias - Unique_Node_List wq; - wq.push(mem); - - for (uint next = 0; next < wq.size(); next++) { - Node *n = wq.at(next); -#ifdef ASSERT - if (trace) { tty->print("YYY from (2) "); n->dump(); } -#endif - for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { - Node* u = n->fast_out(i); -#ifdef ASSERT - if (trace) { tty->print("YYY processing "); u->dump(); } -#endif - if (u->is_Phi()) { - assert(u->bottom_type() == Type::MEMORY, "strange memory graph"); - if (ShenandoahWriteBarrierNode::should_process_phi(u, alias, C)) { - for (uint j = 1; j < u->req(); j++) { - if (u->in(j) == n) { - Node *c = u->in(0)->in(j); - if (!shenandoah_fix_mem_phis_helper(c, n, mem_ctrl, rep_ctrl, alias, controls, regions)) { - return false; - } - } - } - } -#ifdef ASSERT - } else if (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) { - if (!shenandoah_fix_mem_phis_helper(u->in(0), n, mem_ctrl, rep_ctrl, alias, controls, regions)) { - return false; - } -#endif - } else if ((u->is_CFG() && u->adr_type() == TypePtr::BOTTOM) || u->Opcode() == Op_Rethrow || u->Opcode() == Op_Return) { - if (!shenandoah_fix_mem_phis_helper(u->in(0), n, mem_ctrl, rep_ctrl, alias, controls, regions)) { - return false; - } - } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(alias) == n) { - wq.push(u); - } else if (u->Opcode() == Op_ShenandoahWriteBarrier && C->get_alias_index(u->adr_type()) == alias) { - Node* m = u->find_out_with(Op_ShenandoahWBMemProj); - if (m != NULL) { - wq.push(m); - } - } - } - } -#ifdef ASSERT - if (trace) { - tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); - for (int i = 0; i < regions.length(); i++) { - Node* r = regions.at(i); - tty->print("%d", i); r->dump(); - } - tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); - } -#endif - - if (regions.length() == 0) { - return true; - } - - { - int i = 0; - for (; i < regions.length(); i+=2) { - Node* region = regions.at(i); - bool has_phi = false; - for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax && !has_phi; j++) { - Node* u = region->fast_out(j); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY && - (u->adr_type() == TypePtr::BOTTOM || C->get_alias_index(u->adr_type()) == alias)) { - has_phi = true; - } - } - if (!has_phi) { - break; - } - } - if (i == regions.length()) { - return true; - } - } - - // Try to restrict the update to path that post dominates rep_ctrl - int k = 0; - int start = 0; - int end = 0; - do { - start = end; - end = k; - for (int i = end; i < regions.length(); i+=2) { - Node* r = regions.at(i); - int prev = k; - for (uint j = 1; j < r->req() && prev == k; j++) { - if (end == 0) { - if (is_dominator(rep_ctrl, r->in(j))) { - Node* mem = regions.at(i+1); - regions.at_put(i, regions.at(k)); - regions.at_put(i+1, regions.at(k+1)); - regions.at_put(k, r); - regions.at_put(k+1, mem); - k+=2; - } - } else { - for (int l = start; l < end && prev == k; l+=2) { - Node* r2 = regions.at(l); - if (is_dominator(r2, r->in(j))) { - Node* mem = regions.at(i+1); - regions.at_put(i, regions.at(k)); - regions.at_put(i+1, regions.at(k+1)); - regions.at_put(k, r); - regions.at_put(k+1, mem); - k+=2; - } - } - } - } - } -#ifdef ASSERT - if (trace) { tty->print_cr("k = %d start = %d end = %d", k, start, end); } -#endif - } while(k != end); - -#ifdef ASSERT - if (end != regions.length()) { - if (trace) { tty->print_cr("Compacting %d -> %d", regions.length(), end); } - } -#endif - regions.trunc_to(end); - -#ifdef ASSERT - if (trace) { - tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); - for (int i = 0; i < regions.length(); i++) { - Node* r = regions.at(i); - tty->print("%d", i); r->dump(); - } - tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); - } -#endif - - // Creating new phis must be done in post order - while (regions.length() > 0) { - int i = 0; - for (; i < regions.length(); i+=2) { - Node* r1 = regions.at(i); - bool is_dom = false; - for (int j = 0; j < regions.length() && !is_dom; j+=2) { - if (i != j) { - Node* r2 = regions.at(j); - for (uint k = 1; k < r2->req() && !is_dom; k++) { - if (is_dominator(r1, r2->in(k))) { - is_dom = true; - } - } - } - } - if (!is_dom) { - break; - } - } - assert(i < regions.length(), "need one"); - Node* r = regions.at(i); - Node* m = regions.at(i+1); - regions.delete_at(i+1); - regions.delete_at(i); - - if (!shenandoah_suitable_mem(m, NULL, NULL)) { - return false; - } - Node* phi = PhiNode::make(r, m, Type::MEMORY, C->get_adr_type(alias)); -#ifdef ASSERT - if (trace) { tty->print("YYY Adding new mem phi "); phi->dump(); } -#endif - register_new_node(phi, r); - - ShenandoahWriteBarrierNode::fix_memory_uses(m, phi, phi, r, C->get_alias_index(phi->adr_type()), this); - assert(phi->outcnt() != 0, "new proj should have uses"); - if (phi->outcnt() == 0) { - _igvn.remove_dead_node(phi); - } - } - - return true; -} - -Node* PhaseIdealLoop::shenandoah_dom_mem(Node* mem, Node*& mem_ctrl, Node* n, Node* rep_ctrl, int alias) { - ResourceMark rm; - VectorSet wq(Thread::current()->resource_area()); - wq.set(mem->_idx); - mem_ctrl = get_ctrl(mem); - while (!ShenandoahBarrierNode::is_dominator(mem_ctrl, rep_ctrl, mem, n, this)) { - mem = next_mem(mem, alias); - if (wq.test_set(mem->_idx)) { - return NULL; // hit an unexpected loop - } - mem_ctrl = ctrl_or_self(mem); - } - if (mem->is_MergeMem()) { - mem = mem->as_MergeMem()->memory_at(alias); - mem_ctrl = ctrl_or_self(mem); - } - return mem; -} - -Node* PhaseIdealLoop::try_common_shenandoah_barriers(Node* n, Node *n_ctrl) { - if (n->is_ShenandoahBarrier() && !C->has_irreducible_loop()) { - // We look for a write barrier whose memory edge dominates n - // Either the replacement write barrier dominates n or we have, - // for instance: - // if ( ) { - // read barrier n - // } else { - // write barrier - // } - // in which case replacing n by the write barrier causes the write - // barrier to move above the if() and the memory Phi that merges - // the memory state for both branches must be updated so both - // inputs become the write barrier's memory projection (and the - // Phi is optimized out) otherwise we risk loosing a memory - // dependency. - // Once we find a replacement write barrier, the code below fixes - // the memory graph in cases like the one above. - Node* val = n->in(ShenandoahBarrierNode::ValueIn); - Node* val_ctrl = get_ctrl(val); - Node* n_proj = n->find_out_with(Op_ShenandoahWBMemProj); - Node* replacement = NULL; - int alias = C->get_alias_index(n->adr_type()); - for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax && replacement == NULL; i++) { - Node* u = val->fast_out(i); - if (u != n && u->Opcode() == Op_ShenandoahWriteBarrier) { - Node* u_mem = u->in(ShenandoahBarrierNode::Memory); - Node* u_proj = u->find_out_with(Op_ShenandoahWBMemProj); - Node* u_ctrl = get_ctrl(u); - Node* u_mem_ctrl = get_ctrl(u_mem); - IdealLoopTree* n_loop = get_loop(n_ctrl); - IdealLoopTree* u_loop = get_loop(u_ctrl); - - Node* ctrl = dom_lca(u_ctrl, n_ctrl); - - if (ctrl->is_Proj() && - ctrl->in(0)->is_Call() && - ctrl->unique_ctrl_out() != NULL && - ctrl->unique_ctrl_out()->Opcode() == Op_Catch && - !is_dominator(val_ctrl, ctrl->in(0)->in(0))) { - continue; - } - - if (n->Opcode() == Op_ShenandoahWriteBarrier && u_proj == NULL && n_proj != NULL) { - continue; - } - - IdealLoopTree* loop = get_loop(ctrl); - - // we don't want to move a write barrier in a loop - if (loop->is_member(u_loop) || (n->Opcode() == Op_ShenandoahWriteBarrier && loop->is_member(n_loop))) { - if (ShenandoahDontIncreaseWBFreq) { - Node* u_iffproj = shenandoah_no_branches(u_ctrl, ctrl, true); - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - Node* n_iffproj = shenandoah_no_branches(n_ctrl, ctrl, true); - if (u_iffproj == NULL || n_iffproj == NULL) { - replacement = u; - } else if (u_iffproj != NodeSentinel && n_iffproj != NodeSentinel && u_iffproj->in(0) == n_iffproj->in(0)) { - replacement = u; - } - } else if (u_iffproj == NULL) { - replacement = u; - } - } else { - replacement = u; - } - } - } - } - if (replacement != NULL) { - Node* old_ctrl = get_ctrl(replacement); - Node* rep_ctrl = dom_lca(n_ctrl, old_ctrl); - if (rep_ctrl->is_Proj() && - rep_ctrl->in(0)->is_Call() && - rep_ctrl->unique_ctrl_out() != NULL && - rep_ctrl->unique_ctrl_out()->Opcode() == Op_Catch) { - rep_ctrl = rep_ctrl->in(0)->in(0); - assert(is_dominator(val_ctrl, rep_ctrl), "bad control"); - } else { - Node* c = try_move_shenandoah_barrier_before_pre_loop(rep_ctrl, val_ctrl); - if (c != NULL) { - rep_ctrl = shenandoah_move_above_predicates(c, val_ctrl); - } else { - while (rep_ctrl->is_IfProj()) { - CallStaticJavaNode* unc = rep_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); - if (unc != NULL) { - int req = unc->uncommon_trap_request(); - Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); - if ((trap_reason == Deoptimization::Reason_loop_limit_check || - trap_reason == Deoptimization::Reason_predicate) && is_dominator(val_ctrl, rep_ctrl->in(0)->in(0))) { - rep_ctrl = rep_ctrl->in(0)->in(0); - continue; - } - } - break; - } - } - } - - Node* mem = replacement->in(ShenandoahBarrierNode::Memory); - Node* old_mem = mem; - Node* rep_proj = replacement->find_out_with(Op_ShenandoahWBMemProj); - { - Node* mem_ctrl = NULL; - - mem = shenandoah_dom_mem(mem, mem_ctrl, n, rep_ctrl, alias); - if (mem == NULL) { - return NULL; - } - - // Add a memory Phi for the slice of the write barrier to any - // region that post dominates rep_ctrl and doesn't have one - // already. - if (rep_proj != NULL && !shenandoah_fix_mem_phis(mem, mem_ctrl, rep_ctrl, alias)) { - return NULL; - } - - assert(shenandoah_memory_dominates_all_paths(mem, rep_ctrl, alias), "can't fix the memory graph"); - } - assert(_igvn.type(mem) == Type::MEMORY, "not memory"); - - if (rep_proj != NULL) { - Node* old_mem = replacement->in(ShenandoahBarrierNode::Memory); - if (!shenandoah_suitable_mem(mem, old_mem, rep_proj)) { - return NULL; - } - - if (replacement->in(ShenandoahBarrierNode::Memory) != mem) { - for (DUIterator_Last imin, i = rep_proj->last_outs(imin); i >= imin; ) { - Node* u = rep_proj->last_out(i); - _igvn.rehash_node_delayed(u); - int uses_found = u->replace_edge(rep_proj, old_mem); - i -= uses_found; - } - _igvn.replace_input_of(replacement, ShenandoahBarrierNode::Memory, mem); - } - set_ctrl_and_loop(replacement, rep_ctrl); - _igvn.replace_input_of(replacement, ShenandoahBarrierNode::Control, rep_ctrl); - - ShenandoahWriteBarrierNode::fix_memory_uses(mem, replacement, rep_proj, rep_ctrl, C->get_alias_index(replacement->adr_type()), this); - assert(rep_proj->outcnt() != 0, "new proj should have uses"); - } else { - if (replacement->in(ShenandoahBarrierNode::Memory) != mem) { - _igvn._worklist.push(replacement->in(ShenandoahBarrierNode::Memory)); - _igvn.replace_input_of(replacement, ShenandoahBarrierNode::Memory, mem); - } - set_ctrl_and_loop(replacement, rep_ctrl); - _igvn.replace_input_of(replacement, ShenandoahBarrierNode::Control, rep_ctrl); - } - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - if (n_proj != NULL) { - lazy_replace(n_proj, n->in(ShenandoahBarrierNode::Memory)); - } - } - lazy_replace(n, replacement); - if (rep_proj != NULL) { - set_ctrl_and_loop(rep_proj, rep_ctrl); - } - return replacement; - } - } - - return NULL; -} - -static void shenandoah_disconnect_barrier_mem(Node* wb, PhaseIterGVN& igvn) { - Node* mem_in = wb->in(ShenandoahBarrierNode::Memory); - Node* proj = wb->find_out_with(Op_ShenandoahWBMemProj); - - for (DUIterator_Last imin, i = proj->last_outs(imin); i >= imin; ) { - Node* u = proj->last_out(i); - igvn.rehash_node_delayed(u); - int nb = u->replace_edge(proj, mem_in); - assert(nb > 0, "no replacement?"); - i -= nb; - } -} - -Node* PhaseIdealLoop::shenandoah_move_above_predicates(Node* cl, Node* val_ctrl) { - Node* entry = cl->in(LoopNode::EntryControl); - Node* above_pred = skip_loop_predicates(entry); - Node* ctrl = entry; - while (ctrl != above_pred) { - Node* next = ctrl->in(0); - if (!is_dominator(val_ctrl, next)) { - break; - } - ctrl = next; - } - return ctrl; -} - -Node* PhaseIdealLoop::try_move_shenandoah_barrier_before_loop_helper(Node* n, Node* cl, Node* val_ctrl, Node* mem) { - assert(cl->is_Loop(), "bad control"); - assert(n->Opcode() == Op_ShenandoahWriteBarrier, "only for shenandoah write barriers"); - Node* ctrl = shenandoah_move_above_predicates(cl, val_ctrl); - Node* mem_ctrl = NULL; - int alias = C->get_alias_index(n->adr_type()); - mem = shenandoah_dom_mem(mem, mem_ctrl, n, ctrl, alias); - if (mem == NULL) { - return NULL; - } - - Node* old_mem = n->in(ShenandoahBarrierNode::Memory); - Node* proj = n->find_out_with(Op_ShenandoahWBMemProj); - if (old_mem != mem && !shenandoah_suitable_mem(mem, old_mem, proj)) { - return NULL; - } - - assert(shenandoah_memory_dominates_all_paths(mem, ctrl, alias), "can't fix the memory graph"); - set_ctrl_and_loop(n, ctrl); - _igvn.replace_input_of(n, ShenandoahBarrierNode::Control, ctrl); - if (old_mem != mem) { - if (proj != NULL) { - shenandoah_disconnect_barrier_mem(n, _igvn); - ShenandoahWriteBarrierNode::fix_memory_uses(mem, n, proj, ctrl, C->get_alias_index(n->adr_type()), this); - assert(proj->outcnt() > 0, "disconnected write barrier"); - } - _igvn.replace_input_of(n, ShenandoahBarrierNode::Memory, mem); - } - if (proj != NULL) { - set_ctrl_and_loop(proj, ctrl); - } - return n; -} - -Node* PhaseIdealLoop::try_move_shenandoah_barrier_before_pre_loop(Node* c, Node* val_ctrl) { - // A write barrier between a pre and main loop can get in the way of - // vectorization. Move it above the pre loop if possible - CountedLoopNode* cl = NULL; - if (c->is_IfFalse() && - c->in(0)->is_CountedLoopEnd()) { - cl = c->in(0)->as_CountedLoopEnd()->loopnode(); - } else if (c->is_IfProj() && - c->in(0)->is_If() && - c->in(0)->in(0)->is_IfFalse() && - c->in(0)->in(0)->in(0)->is_CountedLoopEnd()) { - cl = c->in(0)->in(0)->in(0)->as_CountedLoopEnd()->loopnode(); - } - if (cl != NULL && - cl->is_pre_loop() && - val_ctrl != cl && - is_dominator(val_ctrl, cl)) { - return cl; - } - return NULL; -} - -Node* PhaseIdealLoop::try_move_shenandoah_barrier_before_loop(Node* n, Node *n_ctrl) { - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - IdealLoopTree *n_loop = get_loop(n_ctrl); - Node* val = n->in(ShenandoahBarrierNode::ValueIn); - Node* val_ctrl = get_ctrl(val); - if (n_loop != _ltree_root && !n_loop->_irreducible) { - IdealLoopTree *val_loop = get_loop(val_ctrl); - Node* mem = n->in(ShenandoahBarrierNode::Memory); - IdealLoopTree *mem_loop = get_loop(get_ctrl(mem)); - if (!n_loop->is_member(val_loop) && - n_loop->is_member(mem_loop)) { - Node* n_loop_head = n_loop->_head; - - if (n_loop_head->is_Loop()) { - Node* loop = n_loop_head; - if (n_loop_head->is_CountedLoop() && n_loop_head->as_CountedLoop()->is_main_loop()) { - Node* res = try_move_shenandoah_barrier_before_pre_loop(n_loop_head->in(LoopNode::EntryControl), val_ctrl); - if (res != NULL) { - loop = res; - } - } - - return try_move_shenandoah_barrier_before_loop_helper(n, loop, val_ctrl, mem); - } - } - } - Node* ctrl = try_move_shenandoah_barrier_before_pre_loop(n->in(0), val_ctrl); - if (ctrl != NULL) { - return try_move_shenandoah_barrier_before_loop_helper(n, ctrl, val_ctrl, n->in(ShenandoahBarrierNode::Memory)); - } - } - return NULL; -} - -void PhaseIdealLoop::try_move_shenandoah_read_barrier(Node* n, Node *n_ctrl) { - if (n->Opcode() == Op_ShenandoahReadBarrier) { - ShenandoahReadBarrierNode* rb = (ShenandoahReadBarrierNode*)n; - Node* mem = n->in(MemNode::Memory); - int alias = C->get_alias_index(n->adr_type()); - const bool trace = false; - -#ifdef ASSERT - if (trace) { tty->print("Trying to move mem of"); n->dump(); } -#endif - - Node* new_mem = mem; - - ResourceMark rm; - VectorSet seen(Thread::current()->resource_area()); - Node_List phis; - - for (;;) { -#ifdef ASSERT - if (trace) { tty->print("Looking for dominator from"); mem->dump(); } -#endif - if (mem->is_Proj() && mem->in(0)->is_Start()) { - if (new_mem != n->in(MemNode::Memory)) { -#ifdef ASSERT - if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); n->dump(); } -#endif - _igvn.replace_input_of(n, MemNode::Memory, new_mem); - } - return; - } - - Node* candidate = mem; - do { - if (!rb->is_independent(mem)) { - if (trace) { tty->print_cr("Not independent"); } - if (new_mem != n->in(MemNode::Memory)) { -#ifdef ASSERT - if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); n->dump(); } -#endif - _igvn.replace_input_of(n, MemNode::Memory, new_mem); - } - return; - } - if (seen.test_set(mem->_idx)) { - if (trace) { tty->print_cr("Already seen"); } - ShouldNotReachHere(); - // Strange graph - if (new_mem != n->in(MemNode::Memory)) { -#ifdef ASSERT - if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); n->dump(); } -#endif - _igvn.replace_input_of(n, MemNode::Memory, new_mem); - } - return; - } - if (mem->is_Phi()) { - phis.push(mem); - } - mem = next_mem(mem, alias); - if (mem->bottom_type() == Type::MEMORY) { - candidate = mem; - } - assert(ShenandoahBarrierNode::is_dominator(ctrl_or_self(mem), n_ctrl, mem, n, this) == is_dominator(ctrl_or_self(mem), n_ctrl), "strange dominator"); -#ifdef ASSERT - if (trace) { tty->print("Next mem is"); mem->dump(); } -#endif - } while (mem->bottom_type() != Type::MEMORY || !is_dominator(ctrl_or_self(mem), n_ctrl)); - - assert(mem->bottom_type() == Type::MEMORY, "bad mem"); - - bool not_dom = false; - for (uint i = 0; i < phis.size() && !not_dom; i++) { - Node* nn = phis.at(i); - -#ifdef ASSERT - if (trace) { tty->print("Looking from phi"); nn->dump(); } -#endif - assert(nn->is_Phi(), "phis only"); - for (uint j = 2; j < nn->req() && !not_dom; j++) { - Node* m = nn->in(j); -#ifdef ASSERT - if (trace) { tty->print("Input %d is", j); m->dump(); } -#endif - while (m != mem && !seen.test_set(m->_idx)) { - if (ShenandoahBarrierNode::is_dominator(ctrl_or_self(m), ctrl_or_self(mem), m, mem, this)) { - not_dom = true; - // Scheduling anomaly -#ifdef ASSERT - if (trace) { tty->print("Giving up"); m->dump(); } -#endif - break; - } - if (!rb->is_independent(m)) { - if (trace) { tty->print_cr("Not independent"); } - if (new_mem != n->in(MemNode::Memory)) { -#ifdef ASSERT - if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); n->dump(); } -#endif - _igvn.replace_input_of(n, MemNode::Memory, new_mem); - } - return; - } - if (m->is_Phi()) { - phis.push(m); - } - m = next_mem(m, alias); -#ifdef ASSERT - if (trace) { tty->print("Next mem is"); m->dump(); } -#endif - } - } - } - if (!not_dom) { - new_mem = mem; - phis.clear(); - } else { - seen.Clear(); - } - } - } -} - -CallStaticJavaNode* PhaseIdealLoop::shenandoah_pin_and_expand_barriers_null_check(ShenandoahBarrierNode* wb) { - Node* val = wb->in(ShenandoahBarrierNode::ValueIn); - -#ifdef ASSERT - const Type* val_t = _igvn.type(val); - assert(val_t->meet(TypePtr::NULL_PTR) != val_t, "should be not null"); -#endif - - if (val->Opcode() == Op_CastPP && - val->in(0) != NULL && - val->in(0)->Opcode() == Op_IfTrue && - val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) && - val->in(0)->in(0)->is_If() && - val->in(0)->in(0)->in(1)->Opcode() == Op_Bool && - val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne && - val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && - val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) && - val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { - assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), ""); - CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); - return unc; - } - return NULL; -} - -void PhaseIdealLoop::shenandoah_pin_and_expand_barriers_move_barrier(ShenandoahBarrierNode* wb) { - Node* unc = shenandoah_pin_and_expand_barriers_null_check(wb); - Node* val = wb->in(ShenandoahBarrierNode::ValueIn); - - if (unc != NULL) { - Node* ctrl = get_ctrl(wb); - Node* unc_ctrl = val->in(0); - - Node* branch = shenandoah_no_branches(ctrl, unc_ctrl, false); - assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch"); - if (branch == NodeSentinel) { - return; - } - - Node* mem = wb->in(ShenandoahBarrierNode::Memory); - Node* old_mem = mem; - - Node* mem_ctrl = NULL; - int alias = C->get_alias_index(wb->adr_type()); - mem = shenandoah_dom_mem(mem, mem_ctrl, wb, unc_ctrl, alias); - if (mem == NULL) { - return; - } - - Node* proj = wb->find_out_with(Op_ShenandoahWBMemProj); - if (mem != old_mem && !shenandoah_fix_mem_phis(mem, mem_ctrl, unc_ctrl, alias)) { - return; - } - - assert(mem == old_mem || shenandoah_memory_dominates_all_paths(mem, unc_ctrl, alias), "can't fix the memory graph"); - set_ctrl_and_loop(wb, unc_ctrl); - if (wb->in(ShenandoahBarrierNode::Control) != NULL) { - _igvn.replace_input_of(wb, ShenandoahBarrierNode::Control, unc_ctrl); - } - shenandoah_disconnect_barrier_mem(wb, _igvn); - ShenandoahWriteBarrierNode::fix_memory_uses(mem, wb, proj, unc_ctrl, C->get_alias_index(wb->adr_type()), this); - assert(proj->outcnt() > 0, "disconnected write barrier"); - _igvn.replace_input_of(wb, ShenandoahBarrierNode::Memory, mem); - set_ctrl_and_loop(proj, unc_ctrl); - } -} - -Node* PhaseIdealLoop::shenandoah_pick_phi(Node* phi1, Node* phi2, Node_Stack& phis, VectorSet& visited) { - assert(phis.size() == 0, "stack needs to be empty"); - uint i = 1; - int phi_dominates = -1; - for (;;) { - assert(phi1->req() == phi2->req(), "strange pair of phis"); - assert(phis.size() % 2 == 0, ""); - Node* in1 = phi1->in(i); - Node* in2 = phi2->in(i); - - if (in1->is_MergeMem()) { - in1 = in1->as_MergeMem()->base_memory(); - } - if (in2->is_MergeMem()) { - in2 = in2->as_MergeMem()->base_memory(); - } - - if (in1 == in2) { - //continue - } else if (in1->is_Phi() && in2->is_Phi() && in1->in(0) == in2->in(0)) { - assert(!visited.test_set(in1->_idx), "no loop"); - assert(!visited.test_set(in2->_idx), "no loop"); - phis.push(phi1, i+1); - phis.push(phi2, i+1); - phi1 = in1; - phi2 = in2; - i = 1; - } else { - Node* in1_c = get_ctrl(in1); - Node* in2_c = get_ctrl(in2); - if (ShenandoahBarrierNode::is_dominator(in1_c, in2_c, in1, in2, this)) { - assert(!ShenandoahBarrierNode::is_dominator(in2_c, in1_c, in2, in1, this), "one has to dominate the other"); - assert(phi_dominates == -1 || phi_dominates == 1, "all inputs must dominate"); - phi_dominates = 1; - } else { - assert(ShenandoahBarrierNode::is_dominator(in2_c, in1_c, in2, in1, this), "one must dominate the other"); - assert(!ShenandoahBarrierNode::is_dominator(in1_c, in2_c, in1, in2, this), "one has to dominate the other"); - assert(phi_dominates == -1 || phi_dominates == 2, "all inputs must dominate"); - phi_dominates = 2; - } - } - i++; - - while (i >= phi1->req() && phis.size() > 0) { - i = phis.index(); - phi2 = phis.node(); - phis.pop(); - phi1 = phis.node(); - phis.pop(); - } - - if (i >= phi1->req() && phis.size() == 0) { - Node* phi = NULL; - if (phi_dominates == 1) { - return phi2; - } else if (phi_dominates == 2) { - return phi1; - } else { - return phi1; - } - } - } - return NULL; -} - -bool ShenandoahWriteBarrierNode::mem_is_valid(Node* m, Node* c, PhaseIdealLoop* phase) { - return m != NULL && get_ctrl(m, phase) == c; -} - -Node* ShenandoahWriteBarrierNode::find_raw_mem(Node* ctrl, Node* n, const Node_List& memory_nodes, PhaseIdealLoop* phase) { - assert(n == NULL || phase->ctrl_or_self(n) == ctrl, ""); - Node* raw_mem = memory_nodes[ctrl->_idx]; - Node* c = ctrl; - while (!mem_is_valid(raw_mem, c, phase) && - (!c->is_CatchProj() || raw_mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(raw_mem, phase))) { - c = phase->idom(c); - raw_mem = memory_nodes[c->_idx]; - } - if (n != NULL && mem_is_valid(raw_mem, c, phase)) { - while (!is_dominator_same_ctrl(c, raw_mem, n, phase) && phase->ctrl_or_self(raw_mem) == ctrl) { - raw_mem = next_mem(raw_mem, Compile::AliasIdxRaw); - } - if (raw_mem->is_MergeMem()) { - raw_mem = raw_mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); - } - if (!mem_is_valid(raw_mem, c, phase)) { - do { - c = phase->idom(c); - raw_mem = memory_nodes[c->_idx]; - } while (!mem_is_valid(raw_mem, c, phase) && - (!c->is_CatchProj() || raw_mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(raw_mem, phase))); - } - } - assert(raw_mem->bottom_type() == Type::MEMORY, ""); - return raw_mem; -} - -Node* PhaseIdealLoop::shenandoah_find_bottom_mem(Node* ctrl) { - Node* mem = NULL; - Node* c = ctrl; - do { - if (c->is_Region()) { - Node* phi_bottom = NULL; - for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { - Node* u = c->fast_out(i); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY) { - if (u->adr_type() == TypePtr::BOTTOM) { - if (phi_bottom != NULL) { - phi_bottom = NodeSentinel; - } else { - phi_bottom = u; - } - } - } - } - if (phi_bottom != NULL) { - if (phi_bottom != NodeSentinel) { - mem = phi_bottom; - } else { - Node* phi = NULL; - ResourceMark rm; - Node_Stack phis(0); - VectorSet visited(Thread::current()->resource_area()); - for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { - Node* u = c->fast_out(i); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY && u->adr_type() == TypePtr::BOTTOM) { - if (phi == NULL) { - phi = u; - } else { - phi = shenandoah_pick_phi(phi, u, phis, visited); - } - } - } - mem = phi; - } - } - } else { - if (c->is_Call() && c->as_Call()->adr_type() != NULL) { - CallProjections projs; - c->as_Call()->extract_projections(&projs, true, false); - if (projs.fallthrough_memproj != NULL) { - if (projs.fallthrough_memproj->adr_type() == TypePtr::BOTTOM) { - if (projs.catchall_memproj == NULL) { - mem = projs.fallthrough_memproj; - } else { - if (is_dominator(projs.fallthrough_catchproj, ctrl)) { - mem = projs.fallthrough_memproj; - } else { - assert(is_dominator(projs.catchall_catchproj, ctrl), "one proj must dominate barrier"); - mem = projs.catchall_memproj; - } - } - } - } else { - Node* proj = c->as_Call()->proj_out(TypeFunc::Memory); - if (proj != NULL && - proj->adr_type() == TypePtr::BOTTOM) { - mem = proj; - } - } - } else { - for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { - Node* u = c->fast_out(i); - if (u->is_Proj() && - u->bottom_type() == Type::MEMORY && - u->adr_type() == TypePtr::BOTTOM) { - assert(c->is_SafePoint() || c->is_MemBar() || c->is_Start(), ""); - assert(mem == NULL, "only one proj"); - mem = u; - } - } - assert(!c->is_Call() || c->as_Call()->adr_type() != NULL || mem == NULL, "no mem projection expected"); - } - } - c = idom(c); - } while (mem == NULL); - return mem; -} - -void PhaseIdealLoop::shenandoah_follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses) { - for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { - Node* u = n->fast_out(i); - if (!u->is_CFG() && get_ctrl(u) == ctrl && (!u->is_Phi() || !u->in(0)->is_Loop() || u->in(LoopNode::LoopBackControl) != n)) { - uses.push(u); - } - } -} - -Node* ShenandoahWriteBarrierNode::get_ctrl(Node* n, PhaseIdealLoop* phase) { - Node* c = phase->get_ctrl(n); - if (n->is_Proj() && n->in(0)->is_Call()) { - assert(c == n->in(0), ""); - CallNode* call = c->as_Call(); - CallProjections projs; - call->extract_projections(&projs, true, false); - if (projs.catchall_memproj != NULL) { - if (projs.fallthrough_memproj == n) { - c = projs.fallthrough_catchproj; - } else { - assert(projs.catchall_memproj == n, ""); - c = projs.catchall_catchproj; - } - } - } - return c; -} - -Node* ShenandoahWriteBarrierNode::ctrl_or_self(Node* n, PhaseIdealLoop* phase) { - if (phase->has_ctrl(n)) - return get_ctrl(n, phase); - else { - assert (n->is_CFG(), "must be a CFG node"); - return n; - } -} - -#ifdef ASSERT -static bool has_never_branch(Node* root) { - for (uint i = 1; i < root->req(); i++) { - Node* in = root->in(i); - if (in != NULL && in->Opcode() == Op_Halt && in->in(0)->is_Proj() && in->in(0)->in(0)->Opcode() == Op_NeverBranch) { - return true; - } - } - return false; -} -#endif - -void ShenandoahWriteBarrierNode::collect_memory_nodes(int alias, Node_List& memory_nodes, PhaseIdealLoop* phase) { - Node_Stack stack(0); - VectorSet visited(Thread::current()->resource_area()); - Node_List regions; - - // Walk the raw memory graph and create a mapping from CFG node to - // memory node. Exclude phis for now. - stack.push(phase->C->root(), 1); - do { - Node* n = stack.node(); - int opc = n->Opcode(); - uint i = stack.index(); - if (i < n->req()) { - Node* mem = NULL; - if (opc == Op_Root) { - Node* in = n->in(i); - int in_opc = in->Opcode(); - if (in_opc == Op_Return || in_opc == Op_Rethrow) { - mem = in->in(TypeFunc::Memory); - } else if (in_opc == Op_Halt) { - if (in->in(0)->is_Region()) { -#ifdef ASSERT - Node* r = in->in(0); - for (uint j = 1; j < r->req(); j++) { - assert(r->in(j)->is_Proj() && r->in(j)->in(0)->Opcode() == Op_NeverBranch, ""); - } -#endif - } else { - Node* proj = in->in(0); - assert(proj->is_Proj(), ""); - Node* in = proj->in(0); - assert(in->is_CallStaticJava() || in->Opcode() == Op_NeverBranch || in->Opcode() == Op_Catch, ""); - if (in->is_CallStaticJava()) { - mem = in->in(TypeFunc::Memory); - } else if (in->Opcode() == Op_Catch) { - Node* call = in->in(0)->in(0); - assert(call->is_Call(), ""); - mem = call->in(TypeFunc::Memory); - } - } - } else { -#ifdef ASSERT - n->dump(); - in->dump(); -#endif - ShouldNotReachHere(); - } - } else { - assert(n->is_Phi() && n->bottom_type() == Type::MEMORY, ""); - assert(n->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(n->adr_type()) == alias, ""); - mem = n->in(i); - } - i++; - stack.set_index(i); - if (mem == NULL) { - continue; - } - for (;;) { - if (visited.test_set(mem->_idx) || mem->is_Start()) { - break; - } - if (mem->is_Phi()) { - stack.push(mem, 2); - mem = mem->in(1); - } else if (mem->is_Proj()) { - stack.push(mem, mem->req()); - mem = mem->in(0); - } else if (mem->is_SafePoint() || mem->is_MemBar()) { - mem = mem->in(TypeFunc::Memory); - } else if (mem->is_MergeMem()) { - mem = mem->as_MergeMem()->memory_at(alias); - } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { - stack.push(mem, mem->req()); - mem = mem->in(MemNode::Memory); - } else { -#ifdef ASSERT - mem->dump(); -#endif - ShouldNotReachHere(); - } - } - } else { - if (n->is_Phi()) { - // Nothing - } else if (!n->is_Root()) { - Node* c = get_ctrl(n, phase); - memory_nodes.map(c->_idx, n); - } - stack.pop(); - } - } while(stack.is_nonempty()); - - // Iterate over CFG nodes in rpo and propagate memory state to - // compute memory state at regions, creating new phis if needed. - Node_List rpo_list; - visited.Clear(); - phase->rpo(phase->C->root(), stack, visited, rpo_list); - Node* root = rpo_list.pop(); - assert(root == phase->C->root(), ""); - - const bool trace = false; -#ifdef ASSERT - if (trace) { - for (int i = rpo_list.size() - 1; i >= 0; i--) { - Node* c = rpo_list.at(i); - if (memory_nodes[c->_idx] != NULL) { - tty->print("X %d", c->_idx); memory_nodes[c->_idx]->dump(); - } - } - } -#endif - uint last = phase->C->unique(); - -#ifdef ASSERT - uint8_t max_depth = 0; - for (LoopTreeIterator iter(phase->ltree_root()); !iter.done(); iter.next()) { - IdealLoopTree* lpt = iter.current(); - max_depth = MAX2(max_depth, lpt->_nest); - } -#endif - - bool progress = true; - int iteration = 0; - Node_List dead_phis; - while (progress) { - progress = false; - iteration++; - assert(iteration <= 2+max_depth || phase->C->has_irreducible_loop(), ""); - if (trace) { tty->print_cr("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } - IdealLoopTree* last_updated_ilt = NULL; - for (int i = rpo_list.size() - 1; i >= 0; i--) { - Node* c = rpo_list.at(i); - - Node* prev_mem = memory_nodes[c->_idx]; - if (c->is_Region()) { - Node* prev_region = regions[c->_idx]; - Node* unique = NULL; - for (uint j = 1; j < c->req() && unique != NodeSentinel; j++) { - Node* m = memory_nodes[c->in(j)->_idx]; - assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || phase->C->has_irreducible_loop() || has_never_branch(phase->C->root()), "expect memory state"); - if (m != NULL) { - if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) { - assert(c->is_Loop() && j == LoopNode::LoopBackControl || phase->C->has_irreducible_loop(), ""); - // continue - } else if (unique == NULL) { - unique = m; - } else if (m == unique) { - // continue - } else { - unique = NodeSentinel; - } - } - } - assert(unique != NULL, "empty phi???"); - if (unique != NodeSentinel) { - if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c) { - dead_phis.push(prev_region); - } - regions.map(c->_idx, unique); - } else { - Node* phi = NULL; - if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c && prev_region->_idx >= last) { - phi = prev_region; - for (uint k = 1; k < c->req(); k++) { - Node* m = memory_nodes[c->in(k)->_idx]; - assert(m != NULL, "expect memory state"); - phi->set_req(k, m); - } - } else { - for (DUIterator_Fast jmax, j = c->fast_outs(jmax); j < jmax && phi == NULL; j++) { - Node* u = c->fast_out(j); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY && - (u->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(u->adr_type()) == alias)) { - phi = u; - for (uint k = 1; k < c->req() && phi != NULL; k++) { - Node* m = memory_nodes[c->in(k)->_idx]; - assert(m != NULL, "expect memory state"); - if (u->in(k) != m) { - phi = NULL; - } - } - } - } - if (phi == NULL) { - phi = new (phase->C) PhiNode(c, Type::MEMORY, phase->C->get_adr_type(alias)); - for (uint k = 1; k < c->req(); k++) { - Node* m = memory_nodes[c->in(k)->_idx]; - assert(m != NULL, "expect memory state"); - phi->init_req(k, m); - } - } - } - assert(phi != NULL, ""); - regions.map(c->_idx, phi); - } - Node* current_region = regions[c->_idx]; - if (current_region != prev_region) { - progress = true; - if (prev_region == prev_mem) { - memory_nodes.map(c->_idx, current_region); - } - } - } else if (prev_mem == NULL || prev_mem->is_Phi() || ctrl_or_self(prev_mem, phase) != c) { - Node* m = memory_nodes[phase->idom(c)->_idx]; - assert(m != NULL, "expect memory state"); - if (m != prev_mem) { - memory_nodes.map(c->_idx, m); - progress = true; - } - } -#ifdef ASSERT - if (trace) { tty->print("X %d", c->_idx); memory_nodes[c->_idx]->dump(); } -#endif - } - } - - // Replace existing phi with computed memory state for that region - // if different (could be a new phi or a dominating memory node if - // that phi was found to be useless). - while (dead_phis.size() > 0) { - Node* n = dead_phis.pop(); - n->replace_by(phase->C->top()); - n->destruct(); - } - for (int i = rpo_list.size() - 1; i >= 0; i--) { - Node* c = rpo_list.at(i); - if (c->is_Region()) { - Node* n = regions[c->_idx]; - if (n->is_Phi() && n->_idx >= last && n->in(0) == c) { - phase->register_new_node(n, c); - } - } - } - for (int i = rpo_list.size() - 1; i >= 0; i--) { - Node* c = rpo_list.at(i); - if (c->is_Region()) { - Node* n = regions[c->_idx]; - for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { - Node* u = c->fast_out(i); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY && - u != n) { - if (u->adr_type() == TypePtr::BOTTOM) { - fix_memory_uses(u, n, n, c, alias, phase); - } else if (phase->C->get_alias_index(u->adr_type()) == alias) { - phase->lazy_replace(u, n); - --i; --imax; - } - } - } - } - } -} - -void ShenandoahWriteBarrierNode::fix_raw_mem(Node* ctrl, Node* region, Node* raw_mem, Node* raw_mem_for_ctrl, Node* raw_mem_phi, - Node_List& memory_nodes, Unique_Node_List& uses, PhaseIdealLoop* phase) { - const bool trace = false; - DEBUG_ONLY(if (trace) { tty->print("ZZZ control is"); ctrl->dump(); }); - DEBUG_ONLY(if (trace) { tty->print("ZZZ mem is"); raw_mem->dump(); }); - GrowableArray phis; - if (raw_mem_for_ctrl != raw_mem) { - Node* old = raw_mem_for_ctrl; - Node* prev = NULL; - while (old != raw_mem) { - assert(old->is_Store() || old->is_LoadStore() || old->is_ClearArray(), ""); - prev = old; - old = old->in(MemNode::Memory); - } - assert(prev != NULL, ""); - memory_nodes.map(ctrl->_idx, raw_mem); - memory_nodes.map(region->_idx, raw_mem_for_ctrl); - phase->igvn().replace_input_of(prev, MemNode::Memory, raw_mem_phi); - } else { - memory_nodes.map(region->_idx, raw_mem_phi); - uses.clear(); - uses.push(region); - for(uint next = 0; next < uses.size(); next++ ) { - Node *n = uses.at(next); - assert(n->is_CFG(), ""); - DEBUG_ONLY(if (trace) { tty->print("ZZZ ctrl"); n->dump(); }); - for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { - Node* u = n->fast_out(i); - if (!u->is_Root() && u->is_CFG() && u != n) { - Node* m = memory_nodes[u->_idx]; - if (u->is_Region() && !has_mem_phi(phase->C, u, Compile::AliasIdxRaw)) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ region"); u->dump(); }); - DEBUG_ONLY(if (trace && m != NULL) { tty->print("ZZZ mem"); m->dump(); }); - - if (!mem_is_valid(m, u, phase) || !m->is_Phi()) { - bool push = true; - bool create_phi = true; - if (phase->is_dominator(region, u)) { - create_phi = false; - } else if (!phase->C->has_irreducible_loop()) { - IdealLoopTree* loop = phase->get_loop(ctrl); - bool do_check = true; - IdealLoopTree* l = loop; - create_phi = false; - while (l != phase->ltree_root()) { - if (phase->is_dominator(l->_head, u) && phase->is_dominator(phase->idom(u), l->_head)) { - create_phi = true; - do_check = false; - break; - } - l = l->_parent; - } - - if (do_check) { - assert(!create_phi, ""); - IdealLoopTree* u_loop = phase->get_loop(u); - if (u_loop != phase->ltree_root() && u_loop->is_member(loop)) { - Node* c = ctrl; - while (!phase->is_dominator(c, u_loop->tail())) { - c = phase->idom(c); - } - if (!phase->is_dominator(c, u)) { - do_check = false; - } - } - } - - if (do_check && phase->is_dominator(phase->idom(u), region)) { - create_phi = true; - } - } - if (create_phi) { - Node* phi = new (phase->C) PhiNode(u, Type::MEMORY, TypeRawPtr::BOTTOM); - phase->register_new_node(phi, u); - phis.push(phi); - DEBUG_ONLY(if (trace) { tty->print("ZZZ new phi"); phi->dump(); }); - if (!mem_is_valid(m, u, phase)) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting mem"); phi->dump(); }); - memory_nodes.map(u->_idx, phi); - } else { - DEBUG_ONLY(if (trace) { tty->print("ZZZ NOT setting mem"); m->dump(); }); - for (;;) { - assert(m->is_Mem() || m->is_LoadStore() || m->is_Proj() /*|| m->is_MergeMem()*/, ""); - Node* next = NULL; - if (m->is_Proj()) { - next = m->in(0); - } else { - next = m->in(MemNode::Memory); - } - if (phase->get_ctrl(next) != u) { - break; - } - if (next->is_MergeMem()) { - assert(phase->get_ctrl(next->as_MergeMem()->memory_at(Compile::AliasIdxRaw)) != u, ""); - break; - } - if (next->is_Phi()) { - assert(next->adr_type() == TypePtr::BOTTOM && next->in(0) == u, ""); - break; - } - m = next; - } - - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting to phi"); m->dump(); }); - assert(m->is_Mem() || m->is_LoadStore(), ""); - phase->igvn().replace_input_of(m, MemNode::Memory, phi); - push = false; - } - } else { - DEBUG_ONLY(if (trace) { tty->print("ZZZ skipping region"); u->dump(); }); - } - if (push) { - uses.push(u); - } - } - } else if (!mem_is_valid(m, u, phase) && - !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1)) { - uses.push(u); - } - } - } - } - for (int i = 0; i < phis.length(); i++) { - Node* n = phis.at(i); - Node* r = n->in(0); - DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi"); n->dump(); }); - for (uint j = 1; j < n->req(); j++) { - Node* m = find_raw_mem(r->in(j), NULL, memory_nodes, phase); - phase->igvn().replace_input_of(n, j, m); - DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi: %d", j); m->dump(); }); - } - } - } - uint last = phase->C->unique(); - MergeMemNode* mm = NULL; - int alias = Compile::AliasIdxRaw; - DEBUG_ONLY(if (trace) { tty->print("ZZZ raw mem is"); raw_mem->dump(); }); - for (DUIterator i = raw_mem->outs(); raw_mem->has_out(i); i++) { - Node* u = raw_mem->out(i); - if (u->_idx < last) { - if (u->is_Mem()) { - if (phase->C->get_alias_index(u->adr_type()) == alias) { - Node* m = find_raw_mem(phase->get_ctrl(u), u, memory_nodes, phase); - if (m != raw_mem) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); - phase->igvn().replace_input_of(u, MemNode::Memory, m); - --i; - } - } - } else if (u->is_MergeMem()) { - MergeMemNode* u_mm = u->as_MergeMem(); - if (u_mm->memory_at(alias) == raw_mem) { - MergeMemNode* newmm = NULL; - for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { - Node* uu = u->fast_out(j); - assert(!uu->is_MergeMem(), "chain of MergeMems?"); - if (uu->is_Phi()) { - assert(uu->adr_type() == TypePtr::BOTTOM, ""); - Node* region = uu->in(0); - int nb = 0; - for (uint k = 1; k < uu->req(); k++) { - if (uu->in(k) == u) { - Node* m = find_raw_mem(region->in(k), NULL, memory_nodes, phase); - if (m != raw_mem) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", k); uu->dump(); }); - if (newmm == NULL || 1) { - newmm = clone_merge_mem(u, raw_mem, alias, m, phase->ctrl_or_self(m), i, phase); - } - if (newmm != u) { - phase->igvn().replace_input_of(uu, k, newmm); - nb++; - --jmax; - } - } - } - } - if (nb > 0) { - --j; - } - } else { - Node* m = find_raw_mem(phase->ctrl_or_self(uu), uu, memory_nodes, phase); - if (m != raw_mem) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); uu->dump(); }); - if (newmm == NULL || 1) { - newmm = clone_merge_mem(u, raw_mem, alias, m, phase->ctrl_or_self(m), i, phase); - } - if (newmm != u) { - phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); - --j, --jmax; - } - } - } - } - } - } else if (u->is_Phi()) { - assert(u->bottom_type() == Type::MEMORY, "what else?"); - if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) { - Node* region = u->in(0); - bool replaced = false; - for (uint j = 1; j < u->req(); j++) { - if (u->in(j) == raw_mem) { - Node* m = find_raw_mem(region->in(j), NULL, memory_nodes, phase); - Node* nnew = m; - if (m != raw_mem) { - if (u->adr_type() == TypePtr::BOTTOM) { - if (mm == NULL || 1) { - mm = allocate_merge_mem(raw_mem, alias, m, phase->ctrl_or_self(m), phase); - } - nnew = mm; - } - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", j); u->dump(); }); - phase->igvn().replace_input_of(u, j, nnew); - replaced = true; - } - } - } - if (replaced) { - --i; - } - } - } else if (u->adr_type() == TypePtr::BOTTOM || u->adr_type() == NULL) { - assert(u->adr_type() != NULL || - u->Opcode() == Op_Rethrow || - u->Opcode() == Op_Return || - u->Opcode() == Op_SafePoint || - (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || - (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || - u->Opcode() == Op_CallLeaf, ""); - Node* m = find_raw_mem(phase->ctrl_or_self(u), u, memory_nodes, phase); - if (m != raw_mem) { - if (mm == NULL || 1) { - mm = allocate_merge_mem(raw_mem, alias, m, phase->get_ctrl(m), phase); - } - phase->igvn().replace_input_of(u, u->find_edge(raw_mem), mm); - --i; - } - } else if (phase->C->get_alias_index(u->adr_type()) == alias) { - Node* m = find_raw_mem(phase->ctrl_or_self(u), u, memory_nodes, phase); - if (m != raw_mem) { - DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); - phase->igvn().replace_input_of(u, u->find_edge(raw_mem), m); - --i; - } - } - } - } -#ifdef ASSERT - assert(raw_mem_phi->outcnt() > 0, ""); - for (int i = 0; i < phis.length(); i++) { - Node* n = phis.at(i); - assert(n->outcnt() > 0, "new phi must have uses now"); - } -#endif -} - -bool ShenandoahBarrierNode::is_evacuation_in_progress_test(Node* iff) { - if (!UseShenandoahGC) { - return false; - } - - assert(iff->is_If(), "bad input"); - if (iff->Opcode() != Op_If) { - return false; - } - Node* bol = iff->in(1); - if (!bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::ne) { - return false; - } - Node* cmp = bol->in(1); - if (cmp->Opcode() != Op_CmpI) { - return false; - } - Node* in1 = cmp->in(1); - Node* in2 = cmp->in(2); - if (in2->find_int_con(-1) != 0) { - return false; - } - if (in1->Opcode() != Op_AndI) { - return false; - } - in2 = in1->in(2); - if (in2->find_int_con(-1) != ShenandoahHeap::EVACUATION) { - return false; - } - in1 = in1->in(1); - - return is_gc_state_load(in1); -} - -bool ShenandoahBarrierNode::is_gc_state_load(Node *n) { - if (!UseShenandoahGC) { - return false; - } - - if (n->Opcode() != Op_LoadB) { - return false; - } - Node* addp = n->in(MemNode::Address); - if (!addp->is_AddP()) { - return false; - } - Node* base = addp->in(AddPNode::Address); - Node* off = addp->in(AddPNode::Offset); - if (base->Opcode() != Op_ThreadLocal) { - return false; - } - if (off->find_intptr_t_con(-1) != in_bytes(JavaThread::gc_state_offset())) { - return false; - } - return true; -} - - -void PhaseIdealLoop::shenandoah_test_evacuation_in_progress(Node* ctrl, int alias, Node*& raw_mem, Node*& wb_mem, - IfNode*& evacuation_iff, Node*& evac_in_progress, - Node*& evac_not_in_progress) { - IdealLoopTree *loop = get_loop(ctrl); - Node* thread = new (C) ThreadLocalNode(); - register_new_node(thread, ctrl); - Node* offset = _igvn.MakeConX(in_bytes(JavaThread::gc_state_offset())); - set_ctrl(offset, C->root()); - Node* gc_state_addr = new (C) AddPNode(C->top(), thread, offset); - register_new_node(gc_state_addr, ctrl); - uint gc_state_idx = Compile::AliasIdxRaw; - const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument - debug_only(gc_state_adr_type = C->get_adr_type(gc_state_idx)); - - Node* gc_state = new (C) LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); - register_new_node(gc_state, ctrl); - - Node* evacuation_in_progress = new (C) AndINode(gc_state, _igvn.intcon(ShenandoahHeap::EVACUATION)); - register_new_node(evacuation_in_progress, ctrl); - Node* evacuation_in_progress_cmp = new (C) CmpINode(evacuation_in_progress, _igvn.zerocon(T_INT)); - register_new_node(evacuation_in_progress_cmp, ctrl); - Node* evacuation_in_progress_test = new (C) BoolNode(evacuation_in_progress_cmp, BoolTest::ne); - register_new_node(evacuation_in_progress_test, ctrl); - evacuation_iff = new (C) IfNode(ctrl, evacuation_in_progress_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); - register_control(evacuation_iff, loop, ctrl); - - assert(ShenandoahBarrierNode::is_evacuation_in_progress_test(evacuation_iff), "Should match the shape"); - assert(ShenandoahBarrierNode::is_gc_state_load(gc_state), "Should match the shape"); - - evac_not_in_progress = new (C) IfFalseNode(evacuation_iff); - register_control(evac_not_in_progress, loop, evacuation_iff); - evac_in_progress = new (C) IfTrueNode(evacuation_iff); - register_control(evac_in_progress, loop, evacuation_iff); -} - -void PhaseIdealLoop::shenandoah_evacuation_not_in_progress_null_check(Node*& c, Node*& val, Node* unc_ctrl, Node*& unc_region) { - if (unc_ctrl != NULL) { - // Clone the null check in this branch to allow implicit null check - IdealLoopTree *loop = get_loop(c); - Node* iff = unc_ctrl->in(0); - assert(iff->is_If(), "broken"); - Node* new_iff = iff->clone(); - new_iff->set_req(0, c); - register_control(new_iff, loop, c); - Node* iffalse = new (C) IfFalseNode(new_iff->as_If()); - register_control(iffalse, loop, new_iff); - Node* iftrue = new (C) IfTrueNode(new_iff->as_If()); - register_control(iftrue, loop, new_iff); - c = iftrue; - unc_region = new (C) RegionNode(3); - unc_region->init_req(1, iffalse); - const Type *t = _igvn.type(val); - assert(val->Opcode() == Op_CastPP, "expect cast to non null here"); - Node* uncasted_val = val->in(1); - val = new (C) CastPPNode(uncasted_val, t); - val->init_req(0, c); - register_new_node(val, c); - } -} - -void PhaseIdealLoop::shenandoah_evacuation_not_in_progress(Node* c, Node* val, Node* unc_ctrl, Node* raw_mem, Node* wb_mem, Node* region, - Node* val_phi, Node* mem_phi, Node* raw_mem_phi, Node*& unc_region) { - shenandoah_evacuation_not_in_progress_null_check(c, val, unc_ctrl, unc_region); - region->init_req(1, c); - Node *rbfalse = new(C) ShenandoahReadBarrierNode(c, wb_mem, val); - register_new_node(rbfalse, c); - val_phi->init_req(1, rbfalse); - mem_phi->init_req(1, wb_mem); - raw_mem_phi->init_req(1, raw_mem); -} - -void PhaseIdealLoop::shenandoah_evacuation_in_progress_null_check(Node*& c, Node*& val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, - Node* unc_region, Unique_Node_List& uses) { - if (unc != NULL) { - // Clone the null check in this branch to allow implicit null check - IdealLoopTree *loop = get_loop(c); - Node* iff = unc_ctrl->in(0); - assert(iff->is_If(), "broken"); - Node* new_iff = iff->clone(); - new_iff->set_req(0, c); - register_control(new_iff, loop, c); - Node* iffalse = new (C) IfFalseNode(new_iff->as_If()); - register_control(iffalse, loop, new_iff); - Node* iftrue = new (C) IfTrueNode(new_iff->as_If()); - register_control(iftrue, loop, new_iff); - c = iftrue; - unc_region->init_req(2, iffalse); - - Node* proj = iff->as_If()->proj_out(0); - assert(proj != unc_ctrl, "bad projection"); - Node* use = proj->unique_ctrl_out(); - - assert(use == unc || use->is_Region(), "what else?"); - - uses.clear(); - if (use == unc) { - set_idom(use, unc_region, dom_depth(unc_region)+1); - for (uint i = 1; i < unc->req(); i++) { - Node* n = unc->in(i); - if (has_ctrl(n) && get_ctrl(n) == proj) { - uses.push(n); - } - } - } else { - assert(use->is_Region(), "what else?"); - uint idx = 1; - for (; use->in(idx) != proj; idx++); - for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) { - Node* u = use->fast_out(i); - if (u->is_Phi() && get_ctrl(u->in(idx)) == proj) { - uses.push(u->in(idx)); - } - } - } - for(uint next = 0; next < uses.size(); next++ ) { - Node *n = uses.at(next); - assert(get_ctrl(n) == proj, "bad control"); - set_ctrl_and_loop(n, unc_region); - if (n->in(0) == proj) { - _igvn.replace_input_of(n, 0, unc_region); - } - for (uint i = 0; i < n->req(); i++) { - Node* m = n->in(i); - if (m != NULL && has_ctrl(m) && get_ctrl(m) == proj) { - uses.push(m); - } - } - } - - _igvn.rehash_node_delayed(use); - int nb = use->replace_edge(proj, unc_region); - assert(nb == 1, "only use expected"); - register_control(unc_region, _ltree_root, evacuation_iff); - - _igvn.replace_input_of(iff, 1, _igvn.intcon(1)); - const Type *t = _igvn.type(val); - assert(val->Opcode() == Op_CastPP, "expect cast to non null here"); - Node* uncasted_val = val->in(1); - val = new (C) CastPPNode(uncasted_val, t); - val->init_req(0, c); - register_new_node(val, c); - } -} - -void PhaseIdealLoop::shenandoah_in_cset_fast_test(Node*& c, Node* rbtrue, Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, Node* mem_phi, - Node* raw_mem_phi) { - IdealLoopTree *loop = get_loop(c); - Node* raw_rbtrue = new (C) CastP2XNode(c, rbtrue); - register_new_node(raw_rbtrue, c); - Node* cset_offset = new (C) URShiftXNode(raw_rbtrue, _igvn.intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint())); - register_new_node(cset_offset, c); - Node* in_cset_fast_test_base_addr = _igvn.makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr())); - set_ctrl(in_cset_fast_test_base_addr, C->root()); - Node* in_cset_fast_test_adr = new (C) AddPNode(C->top(), in_cset_fast_test_base_addr, cset_offset); - register_new_node(in_cset_fast_test_adr, c); - uint in_cset_fast_test_idx = Compile::AliasIdxRaw; - const TypePtr* in_cset_fast_test_adr_type = NULL; // debug-mode-only argument - debug_only(in_cset_fast_test_adr_type = C->get_adr_type(in_cset_fast_test_idx)); - Node* in_cset_fast_test_load = new (C) LoadBNode(c, raw_mem, in_cset_fast_test_adr, in_cset_fast_test_adr_type, TypeInt::BOOL, MemNode::unordered); - register_new_node(in_cset_fast_test_load, c); - Node* in_cset_fast_test_cmp = new (C) CmpINode(in_cset_fast_test_load, _igvn.zerocon(T_INT)); - register_new_node(in_cset_fast_test_cmp, c); - Node* in_cset_fast_test_test = new (C) BoolNode(in_cset_fast_test_cmp, BoolTest::ne); - register_new_node(in_cset_fast_test_test, c); - IfNode* in_cset_fast_test_iff = new (C) IfNode(c, in_cset_fast_test_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); - register_control(in_cset_fast_test_iff, loop, c); - - Node* in_cset_fast_test_success = new (C) IfFalseNode(in_cset_fast_test_iff); - register_control(in_cset_fast_test_success, loop, in_cset_fast_test_iff); - - region->init_req(3, in_cset_fast_test_success); - val_phi->init_req(3, rbtrue); - mem_phi->init_req(3, wb_mem); - raw_mem_phi->init_req(3, raw_mem); - - Node* in_cset_fast_test_failure = new (C) IfTrueNode(in_cset_fast_test_iff); - register_control(in_cset_fast_test_failure, loop, in_cset_fast_test_iff); - - c = in_cset_fast_test_failure; -} - -void PhaseIdealLoop::shenandoah_evacuation_in_progress(Node* c, Node* val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, - Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, Node* mem_phi, - Node* raw_mem_phi, Node* unc_region, int alias, Unique_Node_List& uses) { - shenandoah_evacuation_in_progress_null_check(c, val, evacuation_iff, unc, unc_ctrl, unc_region, uses); - - IdealLoopTree *loop = get_loop(c); - - Node* rbtrue = new (C) ShenandoahReadBarrierNode(c, wb_mem, val); - register_new_node(rbtrue, c); - - Node* in_cset_fast_test_failure = NULL; - shenandoah_in_cset_fast_test(c, rbtrue, raw_mem, wb_mem, region, val_phi, mem_phi, raw_mem_phi); - - // The slow path stub consumes and produces raw memory in addition - // to the existing memory edges - Node* base = shenandoah_find_bottom_mem(c); - - MergeMemNode* mm = MergeMemNode::make(C, base); - mm->set_memory_at(alias, wb_mem); - mm->set_memory_at(Compile::AliasIdxRaw, raw_mem); - register_new_node(mm, c); - - Node* call = new (C) CallLeafNoFPNode(OptoRuntime::shenandoah_write_barrier_Type(), StubRoutines::shenandoah_wb_C(), "shenandoah_write_barrier", TypeRawPtr::BOTTOM); - call->init_req(TypeFunc::Control, c); - call->init_req(TypeFunc::I_O, C->top()); - call->init_req(TypeFunc::Memory, mm); - call->init_req(TypeFunc::FramePtr, C->top()); - call->init_req(TypeFunc::ReturnAdr, C->top()); - call->init_req(TypeFunc::Parms, rbtrue); - register_control(call, loop, c); - Node* ctrl_proj = new (C) ProjNode(call, TypeFunc::Control); - register_control(ctrl_proj, loop, call); - Node* mem_proj = new (C) ProjNode(call, TypeFunc::Memory); - register_new_node(mem_proj, call); - Node* res_proj = new (C) ProjNode(call, TypeFunc::Parms); - register_new_node(res_proj, call); - Node* res = new (C) CheckCastPPNode(ctrl_proj, res_proj, _igvn.type(val)->is_oopptr()->cast_to_nonconst()); - register_new_node(res, ctrl_proj); - region->init_req(2, ctrl_proj); - val_phi->init_req(2, res); - mem_phi->init_req(2, mem_proj); - raw_mem_phi->init_req(2, mem_proj); - register_control(region, loop, evacuation_iff); - -} - -void PhaseIdealLoop::shenandoah_pin_and_expand_barriers() { - const bool trace = false; - - // Collect raw memory state at CFG points in the entire graph and - // record it in memory_nodes. Optimize the raw memory graph in the - // process. Optimizing the memory graph also makes the memory graph - // simpler. - Node_List memory_nodes; - ShenandoahWriteBarrierNode::collect_memory_nodes(Compile::AliasIdxRaw, memory_nodes, this); - - // Let's try to common write barriers again - for (int i = C->shenandoah_barriers_count(); i > 0; i--) { - ShenandoahBarrierNode* wb = C->shenandoah_barrier(i-1); - Node* ctrl = get_ctrl(wb); - try_common_shenandoah_barriers(wb, ctrl); - } - - for (int i = 0; i < C->shenandoah_barriers_count(); i++) { - ShenandoahBarrierNode* wb = C->shenandoah_barrier(i); - Node* ctrl = get_ctrl(wb); - - Node* val = wb->in(ShenandoahBarrierNode::ValueIn); - if (ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) { - assert(ShenandoahBarrierNode::is_dominator(get_ctrl(val), ctrl->in(0)->in(0), val, ctrl->in(0), this), "can't move"); - set_ctrl(wb, ctrl->in(0)->in(0)); - } else if (ctrl->is_CallRuntime()) { - assert(ShenandoahBarrierNode::is_dominator(get_ctrl(val), ctrl->in(0), val, ctrl, this), "can't move"); - set_ctrl(wb, ctrl->in(0)); - } - - assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "only for write barriers"); - // Look for a null check that dominates this barrier and move the - // barrier right after the null check to enable implicit null - // checks - shenandoah_pin_and_expand_barriers_move_barrier(wb); - - ctrl = get_ctrl(wb); - } - - Unique_Node_List uses; - Unique_Node_List uses_to_ignore; - for (int i = C->shenandoah_barriers_count(); i > 0; i--) { - int cnt = C->shenandoah_barriers_count(); - ShenandoahBarrierNode* wb = C->shenandoah_barrier(i-1); - assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "only for write barriers"); - - uint last = C->unique(); - Node* ctrl = get_ctrl(wb); - - Node* raw_mem = ShenandoahWriteBarrierNode::find_raw_mem(ctrl, wb, memory_nodes, this); - Node* init_raw_mem = raw_mem; - Node* raw_mem_for_ctrl = ShenandoahWriteBarrierNode::find_raw_mem(ctrl, NULL, memory_nodes, this); - int alias = C->get_alias_index(wb->adr_type()); - Node* wb_mem = wb->in(ShenandoahBarrierNode::Memory); - - Node* val = wb->in(ShenandoahBarrierNode::ValueIn); - Node* wbproj = wb->find_out_with(Op_ShenandoahWBMemProj); - IdealLoopTree *loop = get_loop(ctrl); - - assert(val->Opcode() != Op_ShenandoahWriteBarrier || C->has_irreducible_loop(), "No chain of write barriers"); - - CallStaticJavaNode* unc = shenandoah_pin_and_expand_barriers_null_check(wb); - Node* unc_ctrl = NULL; - if (unc != NULL) { - if (val->in(0) != ctrl) { - unc = NULL; - } else { - unc_ctrl = val->in(0); - } - } - - Node* uncasted_val = val; - if (unc != NULL) { - uncasted_val = val->in(1); - } - - Node* evac_in_progress = NULL; - Node* evac_not_in_progress = NULL; - IfNode* evacuation_iff = NULL; - shenandoah_test_evacuation_in_progress(ctrl, alias, raw_mem, wb_mem, evacuation_iff, evac_in_progress, evac_not_in_progress); - - Node* region = new (C) RegionNode(4); - Node* val_phi = new (C) PhiNode(region, val->bottom_type()->is_oopptr()->cast_to_nonconst()); - Node* mem_phi = PhiNode::make(region, wb_mem, Type::MEMORY, C->alias_type(wb->adr_type())->adr_type()); - Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); - - Node* unc_region = NULL; - shenandoah_evacuation_not_in_progress(evac_not_in_progress, val, unc_ctrl, raw_mem, wb_mem, - region, val_phi, mem_phi, raw_mem_phi, unc_region); - - shenandoah_evacuation_in_progress(evac_in_progress, val, evacuation_iff, unc, unc_ctrl, - raw_mem, wb_mem, region, val_phi, mem_phi, raw_mem_phi, - unc_region, alias, uses); - Node* out_val = val_phi; - register_new_node(val_phi, region); - register_new_node(mem_phi, region); - register_new_node(raw_mem_phi, region); - - // Update the control of all nodes that should be after the - // barrier control flow - uses.clear(); - // Every node that is control dependent on the barrier's input - // control will be after the expanded barrier. The raw memory (if - // its memory is control dependent on the barrier's input control) - // must stay above the barrier. - uses_to_ignore.clear(); - if (has_ctrl(init_raw_mem) && get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) { - uses_to_ignore.push(init_raw_mem); - } - for (uint next = 0; next < uses_to_ignore.size(); next++) { - Node *n = uses_to_ignore.at(next); - for (uint i = 0; i < n->req(); i++) { - Node* in = n->in(i); - if (in != NULL && has_ctrl(in) && get_ctrl(in) == ctrl) { - uses_to_ignore.push(in); - } - } - } - for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) { - Node* u = ctrl->fast_out(i); - if (u->_idx < last && - u != wb && - !uses_to_ignore.member(u) && - (u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) && - (ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) { - Node* old_c = ctrl_or_self(u); - Node* c = old_c; - if (c != ctrl || - ShenandoahBarrierNode::is_dominator_same_ctrl(old_c, wb, u, this) || - u->is_shenandoah_state_load()) { - _igvn.rehash_node_delayed(u); - int nb = u->replace_edge(ctrl, region); - if (u->is_CFG()) { - if (idom(u) == ctrl) { - set_idom(u, region, dom_depth(region)); - } - } else if (get_ctrl(u) == ctrl) { - assert(u != init_raw_mem, "should leave input raw mem above the barrier"); - uses.push(u); - } - assert(nb == 1, "more than 1 ctrl input?"); - --i, imax -= nb; - } - } - } - - if (wbproj != NULL) { - _igvn.replace_input_of(wbproj, 0, C->top()); - lazy_replace(wbproj, mem_phi); - } - if (unc != NULL) { - for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { - Node* u = val->fast_out(i); - Node* c = ctrl_or_self(u); - if (u != wb && (c != ctrl || ShenandoahBarrierNode::is_dominator_same_ctrl(c, wb, u, this))) { - _igvn.rehash_node_delayed(u); - int nb = u->replace_edge(val, out_val); - --i, imax -= nb; - } - } - if (val->outcnt() == 0) { - lazy_update(val, out_val); - _igvn._worklist.push(val); - } - } - lazy_replace(wb, out_val); - - shenandoah_follow_barrier_uses(mem_phi, ctrl, uses); - shenandoah_follow_barrier_uses(out_val, ctrl, uses); - - for(uint next = 0; next < uses.size(); next++ ) { - Node *n = uses.at(next); - assert(get_ctrl(n) == ctrl, "bad control"); - assert(n != init_raw_mem, "should leave input raw mem above the barrier"); - set_ctrl(n, region); - shenandoah_follow_barrier_uses(n, ctrl, uses); - } - - recompute_dom_depth(); - - // The slow path call produces memory: hook the raw memory phi - // from the expanded write barrier with the rest of the graph - // which may require adding memory phis at every post dominated - // region and at enclosing loop heads. Use the memory state - // collected in memory_nodes to fix the memory graph. Update that - // memory state as we go. - ShenandoahWriteBarrierNode::fix_raw_mem(ctrl, region, init_raw_mem, raw_mem_for_ctrl, raw_mem_phi, memory_nodes, uses, this); - assert(C->shenandoah_barriers_count() == cnt - 1, "not replaced"); - } - - assert(C->shenandoah_barriers_count() == 0, "all write barrier nodes should have been replaced"); -} - -#ifdef ASSERT -void ShenandoahBarrierNode::verify_raw_mem(RootNode* root) { - const bool trace = false; - ResourceMark rm; - Unique_Node_List nodes; - Unique_Node_List controls; - Unique_Node_List memories; - - nodes.push(root); - for (uint next = 0; next < nodes.size(); next++) { - Node *n = nodes.at(next); - if (n->Opcode() == Op_CallLeafNoFP && n->as_Call()->_entry_point == StubRoutines::shenandoah_wb_C()) { - controls.push(n); - if (trace) { tty->print("XXXXXX verifying"); n->dump(); } - for (uint next2 = 0; next2 < controls.size(); next2++) { - Node *m = controls.at(next2); - if (!m->is_Loop() || controls.member(m->in(LoopNode::EntryControl)) || 1) { - for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { - Node* u = m->fast_out(i); - if (u->is_CFG() && !u->is_Root() && - !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1)) { - if (trace) { tty->print("XXXXXX pushing control"); u->dump(); } - controls.push(u); - } - } - } - } - memories.push(n->as_Call()->proj_out(TypeFunc::Memory)); - for (uint next2 = 0; next2 < memories.size(); next2++) { - Node *m = memories.at(next2); - assert(m->bottom_type() == Type::MEMORY, ""); - if (!m->is_Phi() || !m->in(0)->is_Loop() || controls.member(m->in(0)->in(LoopNode::EntryControl)) || 1) { - for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { - Node* u = m->fast_out(i); - if (u->bottom_type() == Type::MEMORY && (u->is_Mem() || u->is_ClearArray())) { - if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } - memories.push(u); - } else if (u->is_LoadStore()) { - if (trace) { tty->print("XXXXXX pushing memory"); u->find_out_with(Op_SCMemProj)->dump(); } - memories.push(u->find_out_with(Op_SCMemProj)); - } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(Compile::AliasIdxRaw) == m) { - if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } - memories.push(u); - } else if (u->is_Phi()) { - assert(u->bottom_type() == Type::MEMORY, ""); - if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) { - assert(controls.member(u->in(0)), ""); - if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } - memories.push(u); - } - } else if (u->is_SafePoint() || u->is_MemBar()) { - for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { - Node* uu = u->fast_out(j); - if (uu->bottom_type() == Type::MEMORY) { - if (trace) { tty->print("XXXXXX pushing memory"); uu->dump(); } - memories.push(uu); - } - } - } - } - } - } - for (uint next2 = 0; next2 < controls.size(); next2++) { - Node *m = controls.at(next2); - if (m->is_Region()) { - bool all_in = true; - for (uint i = 1; i < m->req(); i++) { - if (!controls.member(m->in(i))) { - all_in = false; - break; - } - } - if (trace) { tty->print("XXX verifying %s", all_in ? "all in" : ""); m->dump(); } - bool found_phi = false; - for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax && !found_phi; j++) { - Node* u = m->fast_out(j); - if (u->is_Phi() && memories.member(u)) { - found_phi = true; - for (uint i = 1; i < u->req() && found_phi; i++) { - Node* k = u->in(i); - if (memories.member(k) != controls.member(m->in(i))) { - found_phi = false; - } - } - } - } - assert(found_phi || all_in, ""); - } - } - controls.clear(); - memories.clear(); - } - for( uint i = 0; i < n->len(); ++i ) { - Node *m = n->in(i); - if (m != NULL) { - nodes.push(m); - } - } - } -} -#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/shenandoahSupport.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_OPTO_SHENANDOAH_SUPPORT_HPP -#define SHARE_VM_OPTO_SHENANDOAH_SUPPORT_HPP - -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" -#include "memory/allocation.hpp" -#include "opto/addnode.hpp" -#include "opto/graphKit.hpp" -#include "opto/machnode.hpp" -#include "opto/memnode.hpp" -#include "opto/multnode.hpp" -#include "opto/node.hpp" - -class PhaseGVN; - - -class ShenandoahBarrierNode : public TypeNode { -private: - bool _allow_fromspace; - -#ifdef ASSERT - enum verify_type { - ShenandoahLoad, - ShenandoahStore, - ShenandoahValue, - ShenandoahNone - }; - - static bool verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used); -#endif - -public: - -public: - enum { Control, - Memory, - ValueIn - }; - - ShenandoahBarrierNode(Node* ctrl, Node* mem, Node* obj, bool allow_fromspace) - : TypeNode(obj->bottom_type()->isa_oopptr() ? obj->bottom_type()->is_oopptr()->cast_to_nonconst() : obj->bottom_type(), 3), - _allow_fromspace(allow_fromspace) { - - init_req(Control, ctrl); - init_req(Memory, mem); - init_req(ValueIn, obj); - - init_class_id(Class_ShenandoahBarrier); - } - - static Node* skip_through_barrier(Node* n); - - static const TypeOopPtr* brooks_pointer_type(const Type* t) { - return t->is_oopptr()->cast_to_nonconst()->add_offset(ShenandoahBrooksPointer::byte_offset())->is_oopptr(); - } - - virtual const TypePtr* adr_type() const { - if (bottom_type() == Type::TOP) { - return NULL; - } - //const TypePtr* adr_type = in(MemNode::Address)->bottom_type()->is_ptr(); - const TypePtr* adr_type = brooks_pointer_type(bottom_type()); - assert(adr_type->offset() == ShenandoahBrooksPointer::byte_offset(), "sane offset"); - assert(Compile::current()->alias_type(adr_type)->is_rewritable(), "brooks ptr must be rewritable"); - return adr_type; - } - - virtual uint ideal_reg() const { return Op_RegP; } - virtual uint match_edge(uint idx) const { - return idx >= ValueIn; - } - - Node* Identity_impl(PhaseTransform* phase); - - virtual const Type* Value(PhaseTransform* phase) const; - virtual bool depends_only_on_test() const { - return true; - }; - - static bool is_evacuation_in_progress_test(Node *n); - static bool is_gc_state_load(Node *n); - - static bool needs_barrier(PhaseTransform* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace); - -#ifdef ASSERT - static void report_verify_failure(const char* msg, Node* n1 = NULL, Node* n2 = NULL); - static void verify(RootNode* root); - static void verify_raw_mem(RootNode* root); -#endif -#ifndef PRODUCT - virtual void dump_spec(outputStream *st) const; -#endif - static void do_cmpp_if(GraphKit& kit, Node*& taken_branch, Node*& untaken_branch, Node*& taken_memory, Node*& untaken_memory); - -protected: - uint hash() const; - uint cmp(const Node& n) const; - uint size_of() const; - -private: - static bool needs_barrier_impl(PhaseTransform* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace, Unique_Node_List &visited); - - - static bool dominates_memory(PhaseTransform* phase, Node* b1, Node* b2, bool linear); - static bool dominates_memory_impl(PhaseTransform* phase, Node* b1, Node* b2, Node* current, bool linear); - -public: - static bool is_dominator(Node *d_c, Node *n_c, Node* d, Node* n, PhaseIdealLoop* phase); - static bool is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase); -}; - -class ShenandoahReadBarrierNode : public ShenandoahBarrierNode { -public: - ShenandoahReadBarrierNode(Node* ctrl, Node* mem, Node* obj) - : ShenandoahBarrierNode(ctrl, mem, obj, true) { - assert(UseShenandoahGC && (ShenandoahReadBarrier || - ShenandoahWriteBarrier || - ShenandoahAcmpBarrier), - "should be enabled"); - } - ShenandoahReadBarrierNode(Node* ctrl, Node* mem, Node* obj, bool allow_fromspace) - : ShenandoahBarrierNode(ctrl, mem, obj, allow_fromspace) { - assert(UseShenandoahGC && (ShenandoahReadBarrier || - ShenandoahWriteBarrier || - ShenandoahAcmpBarrier), - "should be enabled"); - } - - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); - virtual Node* Identity(PhaseTransform* phase); - virtual int Opcode() const; - - bool is_independent(Node* mem); - -private: - static bool is_independent(const Type* in_type, const Type* this_type); - static bool dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2, bool linear); - static bool dominates_memory_rb_impl(PhaseTransform* phase, Node* b1, Node* b2, Node* current, bool linear); -}; - -class ShenandoahWriteBarrierNode : public ShenandoahBarrierNode { -public: - ShenandoahWriteBarrierNode(Compile* C, Node* ctrl, Node* mem, Node* obj) - : ShenandoahBarrierNode(ctrl, mem, obj, false) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled"); - C->add_shenandoah_barrier(this); - } - - virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); - virtual Node* Identity(PhaseTransform* phase); - virtual bool depends_only_on_test() const { return false; } - - static bool should_process_phi(Node* phi, int alias, Compile* C); - static void fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl, int alias, PhaseIdealLoop* phase); - static MergeMemNode* allocate_merge_mem(Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, PhaseIdealLoop* phase); - static MergeMemNode* clone_merge_mem(Node* u, Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, DUIterator& i, PhaseIdealLoop* phase); - static Node* find_raw_mem(Node* ctrl, Node* wb, const Node_List& memory_nodes, PhaseIdealLoop* phase); - static void collect_memory_nodes(int alias, Node_List& memory_nodes, PhaseIdealLoop* phase); - static void fix_raw_mem(Node* ctrl, Node* region, Node* raw_mem, Node* raw_mem_for_ctrl, - Node* raw_mem_phi, Node_List& memory_nodes, - Unique_Node_List& uses, - PhaseIdealLoop* phase); - static Node* get_ctrl(Node* n, PhaseIdealLoop* phase); - static Node* ctrl_or_self(Node* n, PhaseIdealLoop* phase); - static bool mem_is_valid(Node* m, Node* c, PhaseIdealLoop* phase); - - // virtual void set_req( uint i, Node *n ) { - // if (i == MemNode::Memory) { assert(n == Compiler::current()->immutable_memory(), "set only immutable mem on wb"); } - // Node::set_req(i, n); - // } -}; - -class ShenandoahWBMemProjNode : public ProjNode { -public: - enum {SWBMEMPROJCON = (uint)-3}; - ShenandoahWBMemProjNode(Node *src) : ProjNode( src, SWBMEMPROJCON) { - assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled"); - assert(src->Opcode() == Op_ShenandoahWriteBarrier || src->is_Mach(), "epxect wb"); - } - virtual Node* Identity(PhaseTransform* phase); - - virtual int Opcode() const; - virtual bool is_CFG() const { return false; } - virtual const Type *bottom_type() const {return Type::MEMORY;} - virtual const TypePtr *adr_type() const { - Node* wb = in(0); - if (wb == NULL || wb->is_top()) return NULL; // node is dead - assert(wb->Opcode() == Op_ShenandoahWriteBarrier || (wb->is_Mach() && wb->as_Mach()->ideal_Opcode() == Op_ShenandoahWriteBarrier), "expect wb"); - return ShenandoahBarrierNode::brooks_pointer_type(wb->bottom_type()); - } - - virtual uint ideal_reg() const { return 0;} // memory projections don't have a register - virtual const Type *Value(PhaseTransform* phase ) const { - return bottom_type(); - } -#ifndef PRODUCT - virtual void dump_spec(outputStream *st) const {}; -#endif -}; - -#endif // SHARE_VM_OPTO_SHENANDOAH_SUPPORT_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/split_if.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/split_if.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/split_if.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/split_if.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -73,8 +73,7 @@ if( n->is_Phi() ) return false; // Local PHIs are expected // Recursively split-up inputs - uint first_input = n->Opcode() == Op_ShenandoahWBMemProj ? 0 : 1; - for (uint i = first_input; i < n->req(); i++) { + for (uint i = 1; i < n->req(); i++) { if( split_up( n->in(i), blk1, blk2 ) ) { // Got split recursively and self went dead? if (n->outcnt() == 0) @@ -217,7 +216,6 @@ register_new_node(phi, blk1); // Remove cloned-up value from optimizer; use phi instead - split_mem_thru_phi(n, blk1, phi); _igvn.replace_node( n, phi ); // (There used to be a self-recursive call to split_up() here, diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/stringopts.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/stringopts.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/stringopts.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/stringopts.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -32,7 +32,6 @@ #include "opto/idealKit.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/stringopts.hpp" #include "opto/subnode.hpp" @@ -1187,8 +1186,6 @@ kit.set_control(loop); Node* sizeTable = fetch_static_field(kit, size_table_field); - sizeTable = kit.shenandoah_read_barrier(sizeTable); - Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS); C->record_for_igvn(value); Node* limit = __ CmpI(phi, value); @@ -1382,8 +1379,6 @@ Node* count = kit.load_String_length(kit.control(), string); Node* value = kit.load_String_value (kit.control(), string); - value = kit.shenandoah_read_barrier(value); - // copy the contents if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) { // For small constant strings just emit individual stores. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/subnode.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/subnode.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/subnode.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/subnode.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,10 +34,12 @@ #include "opto/mulnode.hpp" #include "opto/opcodes.hpp" #include "opto/phaseX.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" -#include "opto/shenandoahSupport.hpp" #include "runtime/sharedRuntime.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/shenandoah/shenandoahBarrierSetC2.hpp" +#include "gc_implementation/shenandoah/shenandoahSupport.hpp" +#endif // Portions of code courtesy of Clifford Click @@ -853,7 +855,9 @@ // or NULL if not matching. #if INCLUDE_ALL_GCS - n = ShenandoahBarrierNode::skip_through_barrier(n); + if (UseShenandoahGC) { + n = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(n); + } #endif if (n->Opcode() != Op_LoadP) return NULL; @@ -903,35 +907,6 @@ // checking to see an unknown klass subtypes a known klass with no subtypes; // this only happens on an exact match. We can shorten this test by 1 load. Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { - if (UseShenandoahGC) { - Node* in1 = in(1); - Node* in2 = in(2); - if (in1->bottom_type() == TypePtr::NULL_PTR) { - in2 = ShenandoahBarrierNode::skip_through_barrier(in2); - } - if (in2->bottom_type() == TypePtr::NULL_PTR) { - in1 = ShenandoahBarrierNode::skip_through_barrier(in1); - } - PhaseIterGVN* igvn = phase->is_IterGVN(); - if (in1 != in(1)) { - if (igvn != NULL) { - set_req_X(1, in1, igvn); - } else { - set_req(1, in1); - } - assert(in2 == in(2), "only one change"); - return this; - } - if (in2 != in(2)) { - if (igvn != NULL) { - set_req_X(2, in2, igvn); - } else { - set_req(2, in2); - } - return this; - } - } - // Normalize comparisons between Java mirrors into comparisons of the low- // level klass, where a dependent load could be shortened. // diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/superword.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/superword.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/superword.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/superword.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -448,6 +448,7 @@ return true; // no induction variable } CountedLoopEndNode* pre_end = get_pre_loop_end(lp()->as_CountedLoop()); + assert(pre_end != NULL, "we must have a correct pre-loop"); assert(pre_end->stride_is_con(), "pre loop stride is constant"); int preloop_stride = pre_end->stride_con(); @@ -2052,7 +2053,7 @@ CountedLoopNode *main_head = lp()->as_CountedLoop(); assert(main_head->is_main_loop(), ""); CountedLoopEndNode* pre_end = get_pre_loop_end(main_head); - assert(pre_end != NULL, ""); + assert(pre_end != NULL, "we must have a correct pre-loop"); Node *pre_opaq1 = pre_end->limit(); assert(pre_opaq1->Opcode() == Op_Opaque1, ""); Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1; @@ -2207,16 +2208,27 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. -CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) { - Node *ctrl = cl->in(LoopNode::EntryControl); +CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { + Node* ctrl = cl->in(LoopNode::EntryControl); if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node *iffm = ctrl->in(0); + Node* iffm = ctrl->in(0); if (!iffm->is_If()) return NULL; - Node *p_f = iffm->in(0); + Node* bolzm = iffm->in(1); + if (!bolzm->is_Bool()) return NULL; + Node* cmpzm = bolzm->in(1); + if (!cmpzm->is_Cmp()) return NULL; + Node* opqzm = cmpzm->in(2); + // Can not optimize a loop if zero-trip Opaque1 node is optimized + // away and then another round of loop opts attempted. + if (opqzm->Opcode() != Op_Opaque1) { + return NULL; + } + Node* p_f = iffm->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; - CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); - if (!pre_end->loopnode()->is_pre_loop()) return NULL; + CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); + CountedLoopNode* loop_node = pre_end->loopnode(); + if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL; return pre_end; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/type.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/type.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/opto/type.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/opto/type.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -28,7 +28,7 @@ #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "compiler/compileLog.hpp" -#include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc_implementation/shenandoah/shenandoahForwarding.hpp" #include "libadt/dict.hpp" #include "memory/gcLocker.hpp" #include "memory/oopFactory.hpp" @@ -2502,8 +2502,6 @@ if (_offset != 0) { if (_offset == oopDesc::klass_offset_in_bytes()) { _is_ptr_to_narrowklass = UseCompressedClassPointers; - } else if (UseShenandoahGC && _offset == ShenandoahBrooksPointer::byte_offset()) { - // Shenandoah doesn't support compressed forwarding pointers } else if (klass() == NULL) { // Array with unknown body type assert(this->isa_aryptr(), "only arrays without klass"); @@ -2529,8 +2527,7 @@ assert(this->isa_instptr(), "must be an instance ptr."); _is_ptr_to_narrowoop = false; } else if (klass() == ciEnv::current()->Class_klass() && - _offset >= InstanceMirrorKlass::offset_of_static_fields() && - !UseShenandoahGC) { + _offset >= InstanceMirrorKlass::offset_of_static_fields()) { // Static fields assert(o != NULL, "must be constant"); ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jni.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jni.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jni.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jni.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -666,7 +666,7 @@ oop super_mirror = JNIHandles::resolve_non_null(super); if (java_lang_Class::is_primitive(sub_mirror) || java_lang_Class::is_primitive(super_mirror)) { - jboolean ret = oopDesc::equals(sub_mirror, super_mirror); + jboolean ret = sub_mirror == super_mirror; #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret); #else /* USDT2 */ @@ -997,7 +997,7 @@ #endif /* USDT2 */ oop a = JNIHandles::resolve(r1); oop b = JNIHandles::resolve(r2); - jboolean ret = oopDesc::equals(a, b) ? JNI_TRUE : JNI_FALSE; + jboolean ret = a == b ? JNI_TRUE : JNI_FALSE; #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret); @@ -2630,7 +2630,7 @@ // If G1 is enabled and we are accessing the value of the referent // field in a reference object then we need to register a non-null // referent with the SATB barrier. - if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { bool needs_barrier = false; if (ret != NULL && diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvm.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvm.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvm.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvm.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -587,7 +587,7 @@ // If G1 is enabled then we need to register a non-null referent // with the SATB barrier. #if INCLUDE_ALL_GCS - if (UseG1GC || UseShenandoahGC) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { oop referent = java_lang_ref_Reference::referent(clone); if (referent != NULL) { G1SATBCardTableModRefBS::enqueue(referent); @@ -595,7 +595,7 @@ } #endif // INCLUDE_ALL_GCS if ((java_lang_ref_Reference::next(clone) != NULL) || - (oopDesc::equals(java_lang_ref_Reference::queue(clone), java_lang_ref_ReferenceQueue::ENQUEUED_queue()))) { + (java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) { // If the source has been enqueued or is being enqueued, don't // register the clone with a queue. java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue()); @@ -654,7 +654,7 @@ // The same is true of StubRoutines::object_copy and the various oop_copy // variants, and of the code generated by the inline_native_clone intrinsic. assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); - Copy::conjoint_jlongs_atomic((jlong*) oopDesc::bs()->read_barrier(obj()), (jlong*)new_obj_oop, + Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop, (size_t)align_object_size(size) / HeapWordsPerLong); // Clear the header new_obj_oop->init_mark(); @@ -1564,7 +1564,7 @@ protection_domain = method->method_holder()->protection_domain(); } - if ((! oopDesc::equals(previous_protection_domain, protection_domain)) && protection_domain != NULL) { + if ((previous_protection_domain != protection_domain) && protection_domain != NULL) { local_array->push(protection_domain); previous_protection_domain = protection_domain; } @@ -3164,7 +3164,7 @@ if (receiver != NULL) { // Check if exception is getting thrown at self (use oop equality, since the // target object might exit) - if (oopDesc::equals(java_thread, thread->threadObj())) { + if (java_thread == thread->threadObj()) { THROW_OOP(java_throwable); } else { // Enques a VM_Operation to stop all threads and then deliver the exception... @@ -3366,7 +3366,7 @@ int count = 0; { - MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock); + MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); // We need to re-resolve the java_thread, since a GC might have happened during the // acquire of the lock JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); @@ -3415,7 +3415,7 @@ // Ensure that the C++ Thread and OSThread structures aren't freed before we operate oop java_thread = JNIHandles::resolve_non_null(jthread); - MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock); + MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); // We need to re-resolve the java_thread, since a GC might have happened during the // acquire of the lock JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); @@ -3430,7 +3430,7 @@ // Ensure that the C++ Thread and OSThread structures aren't freed before we operate oop java_thread = JNIHandles::resolve_non_null(jthread); - MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock); + MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock); // We need to re-resolve the java_thread, since a GC might have happened during the // acquire of the lock JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiEnv.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiEnv.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiEnv.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiEnv.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -308,9 +308,9 @@ !java_lang_Class::is_primitive(mirror)) { Klass* k = java_lang_Class::as_Klass(mirror); assert(k != NULL, "class for non-primitive mirror must exist"); - *size_ptr = (jlong)(k->size() + Universe::heap()->oop_extra_words()) * wordSize; + *size_ptr = (jlong)k->size() * wordSize; } else { - *size_ptr = (jlong)(mirror->size() + Universe::heap()->oop_extra_words()) * wordSize; + *size_ptr = (jlong)mirror->size() * wordSize; } return JVMTI_ERROR_NONE; } /* end GetObjectSize */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiExport.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiExport.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiExport.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiExport.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -704,7 +704,7 @@ public: JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) { _jobj = (jobject)to_jobject(obj); - _size = (obj->size() + Universe::heap()->oop_extra_words()) * wordSize; + _size = obj->size() * wordSize; }; jobject jni_jobject() { return _jobj; } jlong size() { return _size; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiGetLoadedClasses.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiGetLoadedClasses.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiGetLoadedClasses.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiGetLoadedClasses.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -46,7 +46,7 @@ // to get notified about this potential resurrection, otherwise the marking // might not find the object. #if INCLUDE_ALL_GCS - if ((o != NULL) && (UseG1GC || UseShenandoahGC)) { + if ((o != NULL) && (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier))) { G1SATBCardTableModRefBS::enqueue(o); } #endif @@ -60,7 +60,6 @@ void do_klass(Klass* k) { // Collect all jclasses _classStack.push((jclass) _env->jni_reference(k->java_mirror())); - ensure_klass_alive(k->java_mirror()); } int extract(jclass* result_list) { @@ -70,7 +69,10 @@ // Pop all jclasses, fill backwards while (!_classStack.is_empty()) { - result_list[--i] = _classStack.pop(); + jclass klass_handle = _classStack.pop(); + oop klass_mirror = JNIHandles::resolve(klass_handle); + ensure_klass_alive(klass_mirror); + result_list[--i] = klass_handle; } // Return the number of elements written diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiTagMap.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiTagMap.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/jvmtiTagMap.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/jvmtiTagMap.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -166,11 +166,6 @@ static unsigned int hash(oop key, int size) { // shift right to get better distribution (as these bits will be zero // with aligned addresses) -#if INCLUDE_ALL_GCS - if (UseShenandoahGC) { - key = oopDesc::bs()->write_barrier(key); - } -#endif unsigned int addr = (unsigned int)(cast_from_oop(key)); #ifdef _LP64 return (addr >> 3) % size; @@ -307,7 +302,7 @@ unsigned int h = hash(key); JvmtiTagHashmapEntry* entry = _table[h]; while (entry != NULL) { - if (oopDesc::equals(entry->object(), key)) { + if (entry->object() == key) { return entry; } entry = entry->next(); @@ -349,7 +344,7 @@ JvmtiTagHashmapEntry* entry = _table[h]; JvmtiTagHashmapEntry* prev = NULL; while (entry != NULL) { - if (oopDesc::equals(key, entry->object())) { + if (key == entry->object()) { break; } prev = entry; @@ -1526,7 +1521,7 @@ oop o = entry->object(); assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); #if INCLUDE_ALL_GCS - if (UseG1GC || UseShenandoahGC) { + if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { // The reference in this tag map could be the only (implicitly weak) // reference to that object. If we hand it out, we need to keep it live wrt // SATB marking similar to other j.l.ref.Reference referents. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/methodHandles.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/methodHandles.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/methodHandles.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/methodHandles.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -861,7 +861,7 @@ if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor()); - if (!oopDesc::equals(saved, result())) + if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { match_flags = 0; break; // got tired of looking at overflow @@ -914,7 +914,7 @@ // Since this is going through the methods to create MemberNames, don't search // for matching methods already in the table oop saved = MethodHandles::init_method_MemberName(result, info, /*intern*/false); - if (!oopDesc::equals(saved, result())) + if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { match_flags = 0; break; // got tired of looking at overflow diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/unsafe.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/unsafe.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/unsafe.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/unsafe.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,6 +27,7 @@ #include "utilities/macros.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" +#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp" #endif // INCLUDE_ALL_GCS #include "memory/allocation.inline.hpp" #include "prims/jni.h" @@ -167,17 +168,14 @@ #define GET_FIELD(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ - p = oopDesc::bs()->read_barrier(p); \ type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) #define SET_FIELD(obj, offset, type_name, x) \ oop p = JNIHandles::resolve(obj); \ - p = oopDesc::bs()->write_barrier(p); \ *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x) #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ - p = oopDesc::bs()->read_barrier(p); \ if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \ OrderAccess::fence(); \ } \ @@ -185,14 +183,12 @@ #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ oop p = JNIHandles::resolve(obj); \ - p = oopDesc::bs()->write_barrier(p); \ OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x)); // Macros for oops that check UseCompressedOops #define GET_OOP_FIELD(obj, offset, v) \ oop p = JNIHandles::resolve(obj); \ - p = oopDesc::bs()->read_barrier(p); \ oop v; \ if (UseCompressedOops) { \ narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \ @@ -201,7 +197,6 @@ v = *(oop*)index_oop_from_field_offset_long(p, offset); \ } - // Get/SetObject must be special-cased, since it works with handles. // We could be accessing the referent field in a reference @@ -223,7 +218,7 @@ static void ensure_satb_referent_alive(oop o, jlong offset, oop v) { #if INCLUDE_ALL_GCS - if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { + if ((UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { G1SATBCardTableModRefBS::enqueue(v); } #endif @@ -235,6 +230,12 @@ if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); GET_OOP_FIELD(obj, offset, v) +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v); + } +#endif + ensure_satb_referent_alive(p, offset, v); return JNIHandles::make_local(env, v); @@ -243,9 +244,9 @@ UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) UnsafeWrapper("Unsafe_SetObject"); if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); - oop x = oopDesc::bs()->read_barrier(JNIHandles::resolve(x_h)); + oop x = JNIHandles::resolve(x_h); //SET_FIELD(obj, offset, oop, x); - oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)); + oop p = JNIHandles::resolve(obj); if (UseCompressedOops) { if (x != NULL) { // If there is a heap base pointer, we are obliged to emit a store barrier. @@ -271,6 +272,12 @@ UnsafeWrapper("Unsafe_GetObject"); GET_OOP_FIELD(obj, offset, v) +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v); + } +#endif + ensure_satb_referent_alive(p, offset, v); return JNIHandles::make_local(env, v); @@ -278,8 +285,8 @@ UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) UnsafeWrapper("Unsafe_SetObject"); - oop x = oopDesc::bs()->read_barrier(JNIHandles::resolve(x_h)); - oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)); + oop x = JNIHandles::resolve(x_h); + oop p = JNIHandles::resolve(obj); if (UseCompressedOops) { oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); } else { @@ -290,7 +297,6 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) UnsafeWrapper("Unsafe_GetObjectVolatile"); oop p = JNIHandles::resolve(obj); - p = oopDesc::bs()->read_barrier(p); void* addr = index_oop_from_field_offset_long(p, offset); volatile oop v; if (UseCompressedOops) { @@ -300,6 +306,12 @@ (void)const_cast(v = *(volatile oop*) addr); } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + (void)const_cast(v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v)); + } +#endif + ensure_satb_referent_alive(p, offset, v); OrderAccess::acquire(); @@ -310,8 +322,6 @@ UnsafeWrapper("Unsafe_SetObjectVolatile"); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); - x = oopDesc::bs()->read_barrier(x); - p = oopDesc::bs()->write_barrier(p); void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); if (UseCompressedOops) { @@ -360,7 +370,7 @@ } else { Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(oopDesc::bs()->read_barrier(p()), offset)); + jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); jlong value = Atomic::load(addr); return value; @@ -376,7 +386,7 @@ } else { Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(oopDesc::bs()->write_barrier(p()), offset)); + jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); Atomic::store(x, addr); } @@ -464,8 +474,6 @@ UnsafeWrapper("Unsafe_SetOrderedObject"); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); - x = oopDesc::bs()->read_barrier(x); - p = oopDesc::bs()->write_barrier(p); void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); if (UseCompressedOops) { @@ -488,7 +496,7 @@ } else { Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(oopDesc::bs()->write_barrier(p()), offset)); + jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); Atomic::store(x, addr); } @@ -676,7 +684,6 @@ THROW(vmSymbols::java_lang_IllegalArgumentException()); } oop base = JNIHandles::resolve(obj); - base = oopDesc::bs()->write_barrier(base); void* p = index_oop_from_field_offset_long(base, offset); Copy::fill_to_memory_atomic(p, sz, value); UNSAFE_END @@ -706,8 +713,6 @@ } oop srcp = JNIHandles::resolve(srcObj); oop dstp = JNIHandles::resolve(dstObj); - srcp = oopDesc::bs()->read_barrier(srcp); - dstp = oopDesc::bs()->write_barrier(dstp); if (dstp != NULL && !dstp->is_typeArray()) { // NYI: This works only for non-oop arrays at present. // Generalizing it would be reasonable, but requires card marking. @@ -1215,45 +1220,24 @@ oop x = JNIHandles::resolve(x_h); oop e = JNIHandles::resolve(e_h); oop p = JNIHandles::resolve(obj); - - p = oopDesc::bs()->write_barrier(p); - x = oopDesc::bs()->read_barrier(x); - HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); - jboolean success; -#if INCLUDE_ALL_GCS - if (UseShenandoahGC && ShenandoahCASBarrier) { - oop expected; - do { - expected = e; - e = oopDesc::atomic_compare_exchange_oop(x, addr, expected, true); - success = oopDesc::unsafe_equals(e, expected); - } while ((! success) && oopDesc::unsafe_equals(oopDesc::bs()->read_barrier(e), oopDesc::bs()->read_barrier(expected))); - } else -#endif - { - success = oopDesc::unsafe_equals(e, oopDesc::atomic_compare_exchange_oop(x, addr, e, true)); - } - if (! success) { - return false; - } - - update_barrier_set((void*)addr, x); - - return true; + oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true); + jboolean success = (res == e); + if (success) + update_barrier_set((void*)addr, x); + return success; UNSAFE_END UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) UnsafeWrapper("Unsafe_CompareAndSwapInt"); - // We are about to write to this entry so check to see if we need to copy it. - oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)); + oop p = JNIHandles::resolve(obj); jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; UNSAFE_END UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) UnsafeWrapper("Unsafe_CompareAndSwapLong"); - Handle p (THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve(obj))); + Handle p (THREAD, JNIHandles::resolve(obj)); jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); #ifdef SUPPORTS_NATIVE_CX8 return (jlong)(Atomic::cmpxchg(x, addr, e)) == e; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/whitebox.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/whitebox.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/prims/whitebox.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/prims/whitebox.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -305,7 +305,7 @@ WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj)) oop p = JNIHandles::resolve(obj); - return (p->size() + Universe::heap()->oop_extra_words()) * HeapWordSize; + return p->size() * HeapWordSize; WB_END #if INCLUDE_ALL_GCS diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/arguments.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/arguments.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/arguments.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/arguments.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1722,7 +1722,7 @@ UNSUPPORTED_GC_OPTION(UseShenandoahGC); #endif -#ifdef IA32 +#if 0 // leave this block as stepping stone for future platforms warning("Shenandoah GC is not fully supported on this platform:"); warning(" concurrent modes are not supported, only STW cycles are enabled;"); warning(" arch-specific barrier code is not implemented, disabling barriers;"); @@ -1731,11 +1731,13 @@ FLAG_SET_DEFAULT(ShenandoahGCHeuristics, "passive"); FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); - FLAG_SET_DEFAULT(ShenandoahWriteBarrier, false); - FLAG_SET_DEFAULT(ShenandoahReadBarrier, false); + FLAG_SET_DEFAULT(ShenandoahLoadRefBarrier, false); + FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false); + FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, false); FLAG_SET_DEFAULT(ShenandoahCASBarrier, false); - FLAG_SET_DEFAULT(ShenandoahAcmpBarrier, false); FLAG_SET_DEFAULT(ShenandoahCloneBarrier, false); + + FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false); #endif #endif @@ -1773,12 +1775,48 @@ FLAG_SET_DEFAULT(UseNUMA, true); } - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); - - if (FLAG_IS_DEFAULT(ConcGCThreads)) { - uint conc_threads = MAX2((uint) 1, (uint)ParallelGCThreads); - FLAG_SET_DEFAULT(ConcGCThreads, conc_threads); + // Set up default number of concurrent threads. We want to have cycles complete fast + // enough, but we also do not want to steal too much CPU from the concurrently running + // application. Using 1/4 of available threads for concurrent GC seems a good + // compromise here. + bool ergo_conc = FLAG_IS_DEFAULT(ConcGCThreads); + if (ergo_conc) { + FLAG_SET_DEFAULT(ConcGCThreads, MAX2(1, os::processor_count() / 4)); + } + + if (ConcGCThreads == 0) { + vm_exit_during_initialization("Shenandoah expects ConcGCThreads > 0, check -XX:ConcGCThreads=#"); + } + + // Set up default number of parallel threads. We want to have decent pauses performance + // which would use parallel threads, but we also do not want to do too many threads + // that will overwhelm the OS scheduler. Using 1/2 of available threads seems to be a fair + // compromise here. Due to implementation constraints, it should not be lower than + // the number of concurrent threads. + bool ergo_parallel = FLAG_IS_DEFAULT(ParallelGCThreads); + if (ergo_parallel) { + FLAG_SET_DEFAULT(ParallelGCThreads, MAX2(1, os::processor_count() / 2)); + } + + if (ParallelGCThreads == 0) { + vm_exit_during_initialization("Shenandoah expects ParallelGCThreads > 0, check -XX:ParallelGCThreads=#"); + } + + // Make sure ergonomic decisions do not break the thread count invariants. + // This may happen when user overrides one of the flags, but not the other. + // When that happens, we want to adjust the setting that was set ergonomically. + if (ParallelGCThreads < ConcGCThreads) { + if (ergo_conc && !ergo_parallel) { + FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads); + } else if (!ergo_conc && ergo_parallel) { + FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads); + } else if (ergo_conc && ergo_parallel) { + // Should not happen, check the ergonomic computation above. Fail with relevant error. + vm_exit_during_initialization("Shenandoah thread count ergonomic error"); + } else { + // User settings error, report and ask user to rectify. + vm_exit_during_initialization("Shenandoah expects ConcGCThreads <= ParallelGCThreads, check -XX:ParallelGCThreads, -XX:ConcGCThreads"); + } } if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) { @@ -1796,19 +1834,20 @@ #ifdef COMPILER2 // Shenandoah cares more about pause times, rather than raw throughput. // Enabling safepoints in counted loops makes it more responsive with - // long loops. - if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) { - FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true); + // long loops. However, it is risky in 8u, due to bugs it brings, for + // example JDK-8176506. Warn user about this, and proceed. + if (UseCountedLoopSafepoints) { + warning("Enabling -XX:UseCountedLoopSafepoints is known to cause JVM bugs. Use at your own risk."); } #ifdef ASSERT // C2 barrier verification is only reliable when all default barriers are enabled if (ShenandoahVerifyOptoBarriers && (!FLAG_IS_DEFAULT(ShenandoahSATBBarrier) || - !FLAG_IS_DEFAULT(ShenandoahReadBarrier) || - !FLAG_IS_DEFAULT(ShenandoahWriteBarrier) || + !FLAG_IS_DEFAULT(ShenandoahLoadRefBarrier) || + !FLAG_IS_DEFAULT(ShenandoahKeepAliveBarrier) || + !FLAG_IS_DEFAULT(ShenandoahStoreValEnqueueBarrier) || !FLAG_IS_DEFAULT(ShenandoahCASBarrier) || - !FLAG_IS_DEFAULT(ShenandoahAcmpBarrier) || !FLAG_IS_DEFAULT(ShenandoahCloneBarrier) )) { warning("Unusual barrier configuration, disabling C2 barrier verification"); @@ -1853,13 +1892,6 @@ FLAG_SET_DEFAULT(ClassUnloadingWithConcurrentMark, false); } - // JNI fast get field stuff is not currently supported by Shenandoah. - // It would introduce another heap memory access for reading the forwarding - // pointer, which would have to be guarded by the signal handler machinery. - // See: - // http://mail.openjdk.java.net/pipermail/hotspot-dev/2018-June/032763.html - FLAG_SET_DEFAULT(UseFastJNIAccessors, false); - // TLAB sizing policy makes resizing decisions before each GC cycle. It averages // historical data, assigning more recent data the weight according to TLABAllocationWeight. // Current default is good for generational collectors that run frequent young GCs. diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/biasedLocking.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/biasedLocking.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/biasedLocking.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/biasedLocking.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -211,7 +211,7 @@ BasicLock* highest_lock = NULL; for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); - if (oopDesc::equals(mon_info->owner(), obj)) { + if (mon_info->owner() == obj) { if (TraceBiasedLocking && Verbose) { tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")", p2i((void *) mon_info->owner()), @@ -543,7 +543,7 @@ // the bias of the object. markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); - markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED; } @@ -558,8 +558,8 @@ // by another thread so we simply return and let the caller deal // with it. markOop biased_value = mark; - markOop res_mark = obj->cas_set_mark(prototype_header, mark); - assert(! obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked"); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark); + assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked"); return BIAS_REVOKED; } else if (prototype_header->bias_epoch() != mark->bias_epoch()) { // The epoch of this biasing has expired indicating that the @@ -573,14 +573,14 @@ assert(THREAD->is_Java_thread(), ""); markOop biased_value = mark; markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch()); - markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED_AND_REBIASED; } } else { markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); - markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/globals.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/globals.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/globals.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/globals.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -614,6 +614,9 @@ product(bool, UseSHA, false, \ "Control whether SHA instructions can be used on SPARC") \ \ + product(bool, UseGHASHIntrinsics, false, \ + "Use intrinsics for GHASH versions of crypto") \ + \ product(uintx, LargePageSizeInBytes, 0, \ "Large page size (0 to let VM choose the page size)") \ \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/handles.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/handles.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/handles.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/handles.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -78,8 +78,8 @@ // General access oop operator () () const { return obj(); } oop operator -> () const { return non_null_obj(); } - bool operator == (oop o) const { return oopDesc::equals(obj(), o); } - bool operator == (const Handle& h) const { return oopDesc::equals(obj(), h.obj()); } + bool operator == (oop o) const { return obj() == o; } + bool operator == (const Handle& h) const { return obj() == h.obj(); } // Null checks bool is_null() const { return _handle == NULL; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/jniHandles.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/jniHandles.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/jniHandles.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/jniHandles.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -116,7 +116,7 @@ oop result = jweak_ref(handle); result = guard_value(result); #if INCLUDE_ALL_GCS - if (result != NULL && (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier))) { + if (result != NULL && (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier))) { G1SATBCardTableModRefBS::enqueue(result); } #endif // INCLUDE_ALL_GCS @@ -503,7 +503,7 @@ for (JNIHandleBlock* current = this; current != NULL; current = current->_next) { for (int index = 0; index < current->_top; index++) { oop* handle = &(current->_handles)[index]; - if (oopDesc::equals(*handle, JNIHandles::deleted_handle())) { + if (*handle == JNIHandles::deleted_handle()) { // this handle was cleared out by a delete call, reuse it *handle = (oop) _free_list; _free_list = handle; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/jniHandles.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/jniHandles.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/jniHandles.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/jniHandles.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -217,9 +217,9 @@ template inline oop JNIHandles::guard_value(oop value) { if (!external_guard) { - assert(! oopDesc::unsafe_equals(value, badJNIHandle), "Pointing to zapped jni handle area"); - assert(! oopDesc::equals(value, deleted_handle()), "Used a deleted global handle."); - } else if (oopDesc::unsafe_equals(value, badJNIHandle) || (oopDesc::equals(value, deleted_handle()))) { + assert(value != badJNIHandle, "Pointing to zapped jni handle area"); + assert(value != deleted_handle(), "Used a deleted global handle."); + } else if (value == badJNIHandle || value == deleted_handle()) { value = NULL; } return value; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/objectMonitor.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/objectMonitor.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/objectMonitor.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/objectMonitor.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -29,6 +29,8 @@ #include "runtime/park.hpp" #include "runtime/perfData.hpp" +class ObjectMonitor; + // ObjectWaiter serves as a "proxy" or surrogate thread. // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific // ParkEvent instead. Beware, however, that the JVMTI code diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/reflection.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/reflection.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/reflection.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/reflection.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -404,7 +404,7 @@ assert(lower_dim->oop_is_array(), "just checking"); result2 = lower_dim->java_mirror(); } - assert(oopDesc::equals(result, result2), "results must be consistent"); + assert(result == result2, "results must be consistent"); #endif //ASSERT return result; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/safepoint.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/safepoint.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/safepoint.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/safepoint.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -541,6 +541,7 @@ // rotate log files? if (UseGCLogFileRotation) { + TraceTime t8("rotating gc logs", TraceSafepointCleanupTime); gclog_or_tty->rotate_log(false); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stackValue.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stackValue.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stackValue.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stackValue.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -102,8 +102,15 @@ } else { value.noop = *(narrowOop*) value_addr; } - // Decode narrowoop and wrap a handle around the oop - Handle h(oopDesc::decode_heap_oop(value.noop)); + // Decode narrowoop + oop val = oopDesc::decode_heap_oop(value.noop); + // Deoptimization must make sure all oops have passed load barriers +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val); + } +#endif + Handle h(val); // Wrap a handle around the oop return new StackValue(h); } #endif @@ -118,6 +125,12 @@ val = (oop)NULL; } #endif + // Deoptimization must make sure all oops have passed load barriers +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val); + } +#endif Handle h(val); // Wrap a handle around the oop return new StackValue(h); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -124,6 +124,7 @@ address StubRoutines::_aescrypt_decryptBlock = NULL; address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL; address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL; +address StubRoutines::_ghash_processBlocks = NULL; address StubRoutines::_sha1_implCompress = NULL; address StubRoutines::_sha1_implCompressMB = NULL; @@ -156,8 +157,6 @@ address StubRoutines::_safefetchN_fault_pc = NULL; address StubRoutines::_safefetchN_continuation_pc = NULL; -address StubRoutines::_shenandoah_wb_C = NULL; - // Initialization // // Note: to break cycle with universe initialization, stubs are generated in two phases. @@ -178,7 +177,7 @@ StubGenerator_generate(&buffer, false); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size1"); + assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1"); } } @@ -233,7 +232,7 @@ StubGenerator_generate(&buffer, true); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size2"); + assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2"); } #ifdef ASSERT diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/stubRoutines.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -202,6 +202,7 @@ static address _aescrypt_decryptBlock; static address _cipherBlockChaining_encryptAESCrypt; static address _cipherBlockChaining_decryptAESCrypt; + static address _ghash_processBlocks; static address _sha1_implCompress; static address _sha1_implCompressMB; @@ -241,8 +242,6 @@ static address _safefetchN_fault_pc; static address _safefetchN_continuation_pc; - static address _shenandoah_wb_C; - public: // Initialization/Testing static void initialize1(); // must happen before universe::genesis @@ -366,6 +365,7 @@ static address aescrypt_decryptBlock() { return _aescrypt_decryptBlock; } static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; } static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; } + static address ghash_processBlocks() { return _ghash_processBlocks; } static address sha1_implCompress() { return _sha1_implCompress; } static address sha1_implCompressMB() { return _sha1_implCompressMB; } @@ -461,11 +461,6 @@ static void arrayof_jlong_copy (HeapWord* src, HeapWord* dest, size_t count); static void arrayof_oop_copy (HeapWord* src, HeapWord* dest, size_t count); static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count); - - static address shenandoah_wb_C() - { - return _shenandoah_wb_C; - } }; // Safefetch allows to load a value from a location that's not known diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/synchronizer.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/synchronizer.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/synchronizer.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/synchronizer.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -209,7 +209,7 @@ // swing the displaced header from the box back to the mark. if (mark == (markOop) lock) { assert (dhw->is_neutral(), "invariant") ; - if (object->cas_set_mark(dhw, mark) == mark) { + if ((markOop) Atomic::cmpxchg_ptr (dhw, object->mark_addr(), mark) == mark) { TEVENT (fast_exit: release stacklock) ; return; } @@ -231,7 +231,7 @@ // 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((markOop) lock, mark)) { + if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) { TEVENT (slow_enter: release stacklock) ; return ; } @@ -650,7 +650,7 @@ hash = get_next_hash(Self, obj); // allocate a new hash code temp = mark->copy_set_hash(hash); // merge the hash code into header // use (machine word version) atomic operation to install the hash - test = obj->cas_set_mark(temp, mark); + test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark); if (test == mark) { return hash; } @@ -1215,7 +1215,7 @@ if (mark->has_monitor()) { ObjectMonitor * inf = mark->monitor() ; assert (inf->header()->is_neutral(), "invariant"); - assert (oopDesc::equals((oop) inf->object(), object), "invariant") ; + assert (inf->object() == object, "invariant") ; assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); return inf ; } @@ -1262,7 +1262,7 @@ m->_recursions = 0 ; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // Consider: maintain by type/class - markOop cmp = object->cas_set_mark(markOopDesc::INFLATING(), mark); + markOop cmp = (markOop) Atomic::cmpxchg_ptr (markOopDesc::INFLATING(), object->mark_addr(), mark) ; if (cmp != mark) { omRelease (Self, m, true) ; continue ; // Interference -- just retry @@ -1355,7 +1355,7 @@ m->_Responsible = NULL ; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // consider: keep metastats by type/class - if (object->cas_set_mark(markOopDesc::encode(m), mark) != mark) { + if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) { m->set_object (NULL) ; m->set_owner (NULL) ; m->OwnerIsThread = 0 ; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/thread.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/thread.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/thread.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/thread.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1956,7 +1956,7 @@ // from the list of active threads. We must do this after any deferred // card marks have been flushed (above) so that any entries that are // added to the thread's dirty card queue as a result are not lost. - if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { + if (UseG1GC || (UseShenandoahGC)) { flush_barrier_queues(); } if (UseShenandoahGC && UseTLAB && gclab().is_initialized()) { @@ -2046,7 +2046,7 @@ } #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { + if (UseG1GC || (UseShenandoahGC)) { flush_barrier_queues(); } if (UseShenandoahGC && UseTLAB && gclab().is_initialized()) { @@ -3028,7 +3028,6 @@ oop thread_group = java_lang_Thread::threadGroup(thread_obj); if (thread_group != NULL) { typeArrayOop name = java_lang_ThreadGroup::name(thread_group); - name = typeArrayOop(oopDesc::bs()->read_barrier(name)); // ThreadGroup.name can be null if (name != NULL) { const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); @@ -3048,7 +3047,6 @@ oop parent = java_lang_ThreadGroup::parent(thread_group); if (parent != NULL) { typeArrayOop name = java_lang_ThreadGroup::name(parent); - name = typeArrayOop(oopDesc::bs()->read_barrier(name)); // ThreadGroup.name can be null if (name != NULL) { const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vframe.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vframe.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vframe.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vframe.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -135,7 +135,7 @@ // // Skip the monitor that the thread is blocked to enter or waiting on // - if (!found_first_monitor && (oopDesc::equals(obj, pending_obj) || oopDesc::equals(obj, waiting_obj))) { + if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) { continue; } found_first_monitor = true; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vm_operations.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vm_operations.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vm_operations.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vm_operations.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -97,6 +97,8 @@ template(ShenandoahInitMark) \ template(ShenandoahFinalMarkStartEvac) \ template(ShenandoahFinalEvac) \ + template(ShenandoahInitTraversalGC) \ + template(ShenandoahFinalTraversalGC) \ template(ShenandoahInitUpdateRefs) \ template(ShenandoahFinalUpdateRefs) \ template(ShenandoahDegeneratedGC) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vmStructs.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vmStructs.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vmStructs.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vmStructs.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -197,7 +197,6 @@ #include "opto/parse.hpp" #include "opto/regalloc.hpp" #include "opto/rootnode.hpp" -#include "opto/shenandoahSupport.hpp" #include "opto/subnode.hpp" #include "opto/vectornode.hpp" #if defined ADGLOBALS_MD_HPP @@ -820,6 +819,7 @@ static_field(StubRoutines, _aescrypt_decryptBlock, address) \ static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _ghash_processBlocks, address) \ static_field(StubRoutines, _updateBytesCRC32, address) \ static_field(StubRoutines, _crc_table_adr, address) \ static_field(StubRoutines, _multiplyToLen, address) \ @@ -2047,10 +2047,6 @@ declare_c2_type(OverflowAddLNode, OverflowLNode) \ declare_c2_type(OverflowSubLNode, OverflowLNode) \ declare_c2_type(OverflowMulLNode, OverflowLNode) \ - declare_c2_type(ShenandoahBarrierNode, TypeNode) \ - declare_c2_type(ShenandoahReadBarrierNode, ShenandoahBarrierNode) \ - declare_c2_type(ShenandoahWriteBarrierNode, ShenandoahBarrierNode) \ - declare_c2_type(ShenandoahWBMemProjNode, ProjNode) \ \ /*********************/ \ /* Adapter Blob Entries */ \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vmThread.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vmThread.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/runtime/vmThread.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/runtime/vmThread.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -507,6 +507,7 @@ _cur_vm_operation = safepoint_ops; if (_cur_vm_operation != NULL) { do { + EventMark em("Executing coalesced safepoint VM operation: %s", _cur_vm_operation->name()); // evaluate_operation deletes the op object so we have // to grab the next op now VM_Operation* next = _cur_vm_operation->next(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/allocationSite.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/allocationSite.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/allocationSite.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/allocationSite.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -34,8 +34,9 @@ private: NativeCallStack _call_stack; E e; + MEMFLAGS _flag; public: - AllocationSite(const NativeCallStack& stack) : _call_stack(stack) { } + AllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : _call_stack(stack), _flag(flag) { } int hash() const { return _call_stack.hash(); } bool equals(const NativeCallStack& stack) const { return _call_stack.equals(stack); @@ -52,6 +53,8 @@ // Information regarding this allocation E* data() { return &e; } const E* peek() const { return &e; } + + MEMFLAGS flag() const { return _flag; } }; #endif // SHARE_VM_SERVICES_ALLOCATION_SITE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/heapDumper.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/heapDumper.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/heapDumper.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/heapDumper.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -722,6 +722,12 @@ o = oopDesc::load_decode_heap_oop((oop*)addr); } +#if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + o = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(o); + } +#endif + // reflection and sun.misc.Unsafe classes may have a reference to a // Klass* so filter it out. assert(o->is_oop_or_null(), "should always be an oop"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,12 +84,18 @@ // Create pseudo call stack for hashtable entry allocation address pc[3]; if (NMT_TrackingStackDepth >= 3) { - pc[2] = (address)MallocSiteTable::allocation_at; + uintx *fp = (uintx*)MallocSiteTable::allocation_at; + // On ppc64, 'fp' is a pointer to a function descriptor which is a struct of + // three native pointers where the first pointer is the real function address. + // See: http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES + pc[2] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } if (NMT_TrackingStackDepth >= 2) { - pc[1] = (address)MallocSiteTable::lookup_or_add; + uintx *fp = (uintx*)MallocSiteTable::lookup_or_add; + pc[1] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } - pc[0] = (address)MallocSiteTable::new_entry; + uintx *fp = (uintx*)MallocSiteTable::new_entry; + pc[0] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); // Instantiate NativeCallStack object, have to use placement new operator. (see comments above) NativeCallStack* stack = ::new ((void*)_hash_entry_allocation_stack) @@ -158,7 +164,7 @@ MallocSiteHashtableEntry* head = _table[index]; while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { MallocSite* site = head->data(); - if (site->flags() == flags && site->equals(key)) { + if (site->flag() == flags && site->equals(key)) { return head->data(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/mallocSiteTable.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -37,15 +37,12 @@ // MallocSite represents a code path that eventually calls // os::malloc() to allocate memory class MallocSite : public AllocationSite { - private: - MEMFLAGS _flags; - public: MallocSite() : - AllocationSite(NativeCallStack::empty_stack()), _flags(mtNone) {} + AllocationSite(NativeCallStack::empty_stack(), mtNone) {} MallocSite(const NativeCallStack& stack, MEMFLAGS flags) : - AllocationSite(stack), _flags(flags) {} + AllocationSite(stack, flags) {} void allocate(size_t size) { data()->allocate(size); } @@ -55,7 +52,6 @@ size_t size() const { return peek()->size(); } // The number of calls were made size_t count() const { return peek()->count(); } - MEMFLAGS flags() const { return (MEMFLAGS)_flags; } }; // Malloc site hashtable entry diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memBaseline.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memBaseline.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memBaseline.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memBaseline.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) { int res = compare_malloc_site(s1, s2); if (res == 0) { - res = (int)(s1.flags() - s2.flags()); + res = (int)(s1.flag() - s2.flag()); } return res; @@ -209,7 +209,7 @@ const ReservedMemoryRegion* rgn; VirtualMemoryAllocationSite* site; while ((rgn = itr.next()) != NULL) { - VirtualMemoryAllocationSite tmp(*rgn->call_stack()); + VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag()); site = allocation_sites.find(tmp); if (site == NULL) { LinkedListNode* node = diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memoryManager.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memoryManager.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memoryManager.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memoryManager.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -80,7 +80,7 @@ int add_pool(MemoryPool* pool); - bool is_manager(instanceHandle mh) { return oopDesc::equals(mh(), _memory_mgr_obj); } + bool is_manager(instanceHandle mh) { return mh() == _memory_mgr_obj; } virtual instanceOop get_memory_manager_instance(TRAPS); virtual MemoryManager::Name kind() { return MemoryManager::Abstract; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memoryPool.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memoryPool.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memoryPool.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memoryPool.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -100,7 +100,7 @@ // max size could be changed virtual size_t max_size() const { return _max_size; } - bool is_pool(instanceHandle pool) { return (oopDesc::equals(pool(), _memory_pool_obj)); } + bool is_pool(instanceHandle pool) { return pool() == _memory_pool_obj; } bool available_for_allocation() { return _available_for_allocation; } bool set_available_for_allocation(bool value) { @@ -198,7 +198,7 @@ bool support_usage_threshold); MemoryUsage get_memory_usage(); - size_t used_in_bytes() { return _space->used(); } + size_t used_in_bytes() { return _space->used_stable(); } }; #endif // INCLUDE_ALL_GCS diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memReporter.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memReporter.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memReporter.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memReporter.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -205,7 +205,7 @@ const NativeCallStack* stack = malloc_site->call_stack(); stack->print_on(out); out->print("%29s", " "); - MEMFLAGS flag = malloc_site->flags(); + MEMFLAGS flag = malloc_site->flag(); assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone, "Must have a valid memory type"); print_malloc(malloc_site->size(), malloc_site->count(),flag); @@ -231,6 +231,10 @@ stack->print_on(out); out->print("%28s (", " "); print_total(virtual_memory_site->reserved(), virtual_memory_site->committed()); + MEMFLAGS flag = virtual_memory_site->flag(); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } out->print_cr(")\n"); } } @@ -562,24 +566,24 @@ void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(), - 0, 0, malloc_site->flags()); + 0, 0, malloc_site->flag()); } void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(), - malloc_site->count(), malloc_site->flags()); + malloc_site->count(), malloc_site->flag()); } void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early, const MallocSite* current) const { - if (early->flags() != current->flags()) { + if (early->flag() != current->flag()) { // If malloc site type changed, treat it as deallocation of old type and // allocation of new type. old_malloc_site(early); new_malloc_site(current); } else { diff_malloc_site(current->call_stack(), current->size(), current->count(), - early->size(), early->count(), early->flags()); + early->size(), early->count(), early->flag()); } } @@ -603,21 +607,22 @@ void MemDetailDiffReporter::new_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0); + diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0, site->flag()); } void MemDetailDiffReporter::old_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed()); + diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed(), site->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, const VirtualMemoryAllocationSite* current) const { + assert(early->flag() == current->flag(), "Should be the same"); diff_virtual_memory_site(current->call_stack(), current->reserved(), current->committed(), - early->reserved(), early->committed()); + early->reserved(), early->committed(), current->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const { + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const { outputStream* out = output(); // no change @@ -631,6 +636,10 @@ print_virtual_memory_diff(current_reserved, current_committed, early_reserved, early_committed); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } + out->print_cr(")\n"); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memReporter.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memReporter.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/memReporter.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/memReporter.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -218,7 +218,7 @@ void diff_malloc_site(const NativeCallStack* stack, size_t current_size, size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const; void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const; + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; }; #endif // INCLUDE_NMT diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/serviceUtil.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/serviceUtil.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/serviceUtil.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/serviceUtil.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -39,7 +39,7 @@ // to the java world. static inline bool visible_oop(oop o) { // the sentinel for deleted handles isn't visible - if (oopDesc::equals(o, JNIHandles::deleted_handle())) { + if (o == JNIHandles::deleted_handle()) { return false; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/threadService.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/threadService.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/threadService.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/threadService.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -597,7 +597,7 @@ for (int j = 0; j < len; j++) { oop monitor = locked_monitors->at(j); assert(monitor != NULL && monitor->is_instance(), "must be a Java object"); - if (oopDesc::equals(monitor, object)) { + if (monitor == object) { found = true; break; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/virtualMemoryTracker.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/virtualMemoryTracker.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/services/virtualMemoryTracker.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/services/virtualMemoryTracker.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -69,8 +69,8 @@ // Virtual memory allocation site, keeps track where the virtual memory is reserved. class VirtualMemoryAllocationSite : public AllocationSite { public: - VirtualMemoryAllocationSite(const NativeCallStack& stack) : - AllocationSite(stack) { } + VirtualMemoryAllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : + AllocationSite(stack, flag) { } inline void reserve_memory(size_t sz) { data()->reserve_memory(sz); } inline void commit_memory (size_t sz) { data()->commit_memory(sz); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/growableArray.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/growableArray.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/growableArray.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/growableArray.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -27,7 +27,6 @@ #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" -#include "oops/oop.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/top.hpp" @@ -207,15 +206,6 @@ void print(); - inline static bool safe_equals(oop obj1, oop obj2) { - return oopDesc::equals(obj1, obj2); - } - - template - inline static bool safe_equals(X i1, X i2) { - return i1 == i2; - } - int append(const E& elem) { check_nesting(); if (_len == _max) grow(_len); @@ -296,7 +286,7 @@ bool contains(const E& elem) const { for (int i = 0; i < _len; i++) { - if (safe_equals(_data[i], elem)) return true; + if (_data[i] == elem) return true; } return false; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/macros.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/macros.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/macros.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/macros.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -170,8 +170,10 @@ #define TIERED #endif #define COMPILER1_PRESENT(code) code +#define NOT_COMPILER1(code) #else // COMPILER1 #define COMPILER1_PRESENT(code) +#define NOT_COMPILER1(code) code #endif // COMPILER1 // COMPILER2 variant @@ -424,6 +426,14 @@ #define NOT_EMBEDDED(code) code #endif +#ifdef VM_LITTLE_ENDIAN +#define LITTLE_ENDIAN_ONLY(code) code +#define BIG_ENDIAN_ONLY(code) +#else +#define LITTLE_ENDIAN_ONLY(code) +#define BIG_ENDIAN_ONLY(code) code +#endif + #define define_pd_global(type, name, value) const type pd_##name = value; #endif // SHARE_VM_UTILITIES_MACROS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/taskqueue.hpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/taskqueue.hpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/taskqueue.hpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/taskqueue.hpp 2020-01-13 05:52:26.000000000 +0000 @@ -727,6 +727,11 @@ } else { // Otherwise, the queue contained exactly one element; we take the slow // path. + + // The barrier is required to prevent reordering the two reads of _age: + // one is the _age.get() below, and the other is _age.top() above the if-stmt. + // The algorithm may fail if _age.get() reads an older value than _age.top(). + OrderAccess::loadload(); return pop_local_slow(localBot, _age.get()); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/workgroup.cpp openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/workgroup.cpp --- openjdk-8-8u232-b09/=unpacked-tar11=/src/share/vm/utilities/workgroup.cpp 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/src/share/vm/utilities/workgroup.cpp 2020-01-13 05:52:26.000000000 +0000 @@ -464,7 +464,6 @@ if (old == 0) { old = Atomic::cmpxchg(1, &_tasks[t], 0); } - assert(_tasks[t] == 1, "What else?"); bool res = old != 0; #ifdef ASSERT if (!res) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESBase.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESBase.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESBase.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESBase.java 2020-01-13 05:52:26.000000000 +0000 @@ -29,6 +29,7 @@ import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.AlgorithmParameters; @@ -62,8 +63,12 @@ Random random = new Random(0); Cipher cipher; Cipher dCipher; - AlgorithmParameters algParams; + AlgorithmParameters algParams = null; SecretKey key; + GCMParameterSpec gcm_spec; + byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 }; + int tlen = 12; + byte[] iv = new byte[16]; static int numThreads = 0; int threadId; @@ -77,7 +82,10 @@ public void prepare() { try { - System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); + System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 ) testingMisalignment = true; @@ -98,16 +106,24 @@ cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + // CBC init if (mode.equals("CBC")) { - int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0); - IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]); + IvParameterSpec initVector = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, key, initVector); - } else { algParams = cipher.getParameters(); + dCipher.init(Cipher.DECRYPT_MODE, key, initVector); + + // GCM init + } else if (mode.equals("GCM")) { + gcm_init(true); + gcm_init(false); + + // ECB init + } else { cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); } - algParams = cipher.getParameters(); - dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (threadId == 0) { childShowCipher(); } @@ -188,4 +204,19 @@ } abstract void childShowCipher(); + + void gcm_init(boolean encrypt) throws Exception { + gcm_spec = new GCMParameterSpec(tlen * 8, iv); + if (encrypt) { + // Get a new instance everytime because of reuse IV restrictions + cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec); + cipher.updateAAD(aad); + } else { + dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec); + dCipher.updateAAD(aad); + + + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESDecode.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESDecode.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESDecode.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESDecode.java 2020-01-13 05:52:26.000000000 +0000 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(false); + } else if (!noReinit) { + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + } decode = new byte[decodeLength]; if (testingMisalignment) { int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESEncode.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESEncode.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESEncode.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESEncode.java 2020-01-13 05:52:26.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(true); + } else if (!noReinit) { + cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + } encode = new byte[encodeLength]; if (testingMisalignment) { int tempSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESMain.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESMain.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/7184394/TestAESMain.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/7184394/TestAESMain.java 2020-01-13 05:52:26.000000000 +0000 @@ -41,6 +41,13 @@ * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain * * @author Tom Deneau */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2020-01-13 05:52:26.000000000 +0000 @@ -22,9 +22,10 @@ */ import sun.hotspot.WhiteBox; -import sun.misc.Unsafe; import sun.misc.IOUtils; +import sun.misc.Unsafe; +import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; @@ -108,7 +109,13 @@ // (1) Load an anonymous version of this class using the corresponding Unsafe method URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class"); URLConnection connection = classUrl.openConnection(); - byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true); + + int length = connection.getContentLength(); + byte[] classBytes = IOUtils.readAllBytes(connection.getInputStream()); + if (length != -1 && classBytes.length != length) { + throw new IOException("Expected:" + length + ", actual: " + classBytes.length); + } + Class anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null); // (2) Make sure all paths of doWork are profiled and compiled diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/StrangeControl.jasm openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/StrangeControl.jasm --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/StrangeControl.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/StrangeControl.jasm 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class compiler/loopopts/StrangeControl + version 51:0 +{ + +static Field field:"I"; + +public static Method test:"(I)V" + stack 2 locals 2 +{ + iconst_0; + istore 1; + L1: stack_frame_type append; + locals_map int; + iinc 1, 1; + iload 1; + iconst_2; + if_icmple L1; + L2: stack_frame_type same; + iload_0; + putstatic Field field:"I"; + goto L1; +} + +} // end Class StrangeControl diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/superword/TestFuzzPreLoop.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/superword/TestFuzzPreLoop.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8134739 8010500 + * @summary SEGV in SuperWord::get_pre_loop_end + * @run main/othervm compiler.loopopts.superword.TestFuzzPreLoop + */ + +package compiler.loopopts.superword; + +public class TestFuzzPreLoop { + static Object sink; + short sFld = -19206; + + void doTest() { + int[] arr = new int[400]; + + for (int i1 = 0; i1 < 200; i1++) { + for (int i2 = 0; i2 < 100; i2++) { + sink = new int[400]; + } + arr[i1] = 0; + } + + float f1 = 0; + for (int i3 = 0; i3 < 200; i3++) { + f1 += i3 * i3; + } + for (int i4 = 0; i4 < 200; i4++) { + f1 += i4 - sFld; + } + + System.out.println(arr); + System.out.println(f1); + } + + public static void main(String... args) throws Exception { + TestFuzzPreLoop test = new TestFuzzPreLoop(); + for (int i = 0; i < 100; i++) { + test.doTest(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/TestRemoveEmptyLoop.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/TestRemoveEmptyLoop.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/TestRemoveEmptyLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/TestRemoveEmptyLoop.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8231988 + * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation + * TestRemoveEmptyLoop + */ + +public class TestRemoveEmptyLoop { + + public void test() { + int i = 34; + for (; i > 0; i -= 11); + if (i < 0) { + // do nothing + } else { + throw new RuntimeException("Test failed."); + } + } + + public static void main(String[] args) { + TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop(); + for (int i = 0; i < 50000; i++) { + _instance.test(); + } + System.out.println("Test passed."); + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/TestStrangeControl.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/TestStrangeControl.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/loopopts/TestStrangeControl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/loopopts/TestStrangeControl.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8228888 + * @summary Test PhaseIdealLoop::has_local_phi_input() with phi input with non-dominating control. + * @compile StrangeControl.jasm + * @run main/othervm -Xbatch -XX:CompileCommand=inline,compiler.loopopts.StrangeControl::test + * compiler.loopopts.TestStrangeControl + */ + +package compiler.loopopts; + +public class TestStrangeControl { + + public static void main(String[] args) throws Exception { + Thread thread = new Thread() { + public void run() { + // Run this in an own thread because it's basically an endless loop + StrangeControl.test(42); + } + }; + thread.start(); + // Give thread executing strange control loop enough time to trigger OSR compilation + Thread.sleep(4000); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/print/TestProfileReturnTypePrinting.java openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/print/TestProfileReturnTypePrinting.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/compiler/print/TestProfileReturnTypePrinting.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/compiler/print/TestProfileReturnTypePrinting.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8073154 + * @build TestProfileReturnTypePrinting + * @run main/othervm -XX:TypeProfileLevel=020 + * -XX:CompileOnly=TestProfileReturnTypePrinting.testMethod + * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintLIR + * TestProfileReturnTypePrinting + * @summary Verify that c1's LIR that contains ProfileType node could be dumped + * without a crash disregard to an exact class knowledge. + */ +public class TestProfileReturnTypePrinting { + private static final int ITERATIONS = 1_000_000; + + public static void main(String args[]) { + for (int i = 0; i < ITERATIONS; i++) { + TestProfileReturnTypePrinting.testMethod(i); + } + } + + private static int testMethod(int i) { + return TestProfileReturnTypePrinting.foo().hashCode() + + TestProfileReturnTypePrinting.bar(i).hashCode(); + } + + /* Exact class of returned value is known statically. */ + private static B foo() { + return new B(); + } + + /* Exact class of returned value is not known statically. */ + private static Object bar(int i) { + if (i % 2 == 0) { + return new A(); + } else { + return new B(); + } + } + + private static class A { + } + + private static class B extends A { + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/CallMultipleCatchProjs.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/CallMultipleCatchProjs.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/CallMultipleCatchProjs.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/CallMultipleCatchProjs.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8231405 + * @summary barrier expansion breaks if barrier is right after call to rethrow stub + * @key gc + * + * @run main/othervm -XX:CompileOnly=CallMultipleCatchProjs::test -Xcomp -Xverify:none -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC CallMultipleCatchProjs + * + */ + +public class CallMultipleCatchProjs { + private static A field = new A(); + + public static void main(String[] args) throws Exception { + Exception3 exception3 = new Exception3(); + test(new Exception2()); + } + + static int test(Exception exception) throws Exception { + try { + throw exception; + } catch (Exception1 e1) { + return 1; + } catch (Exception2 e2) { + return field.i + 2; + } catch (Exception3 e3) { + return field.i + 3; + } + } + + private static class Exception1 extends Exception { + } + + private static class Exception2 extends Exception { + } + + private static class Exception3 extends Exception { + } + + private static class A { + public int i; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestNullCheck.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestNullCheck.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestNullCheck.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestNullCheck.java 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,7 @@ * @test TestNullCheck * @summary implicit null check on brooks pointer must not cause crash * @key gc + * @requires (vm.bits == "64") * * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation * -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestReferenceCAS.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestReferenceCAS.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestReferenceCAS.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestReferenceCAS.java 2020-01-13 05:52:26.000000000 +0000 @@ -31,6 +31,14 @@ * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-TieredCompilation TestReferenceCAS * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:TieredStopAtLevel=1 TestReferenceCAS * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:TieredStopAtLevel=4 TestReferenceCAS + */ + +/* + * @test TestReferenceCAS + * @summary Shenandoah reference CAS test + * @key gc + * @requires (vm.bits == "64") + * @modules java.base/jdk.internal.misc:+open * * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops TestReferenceCAS * @run main/othervm -Diters=100 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops -Xint TestReferenceCAS diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestWriteBarrierClearControl.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestWriteBarrierClearControl.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/compiler/TestWriteBarrierClearControl.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/compiler/TestWriteBarrierClearControl.java 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,7 @@ * @test TestWriteBarrierClearControl * @summary Clearing control during final graph reshape causes memory barrier to loose dependency on null check * @key gc + * @requires vm.flavor == "server" * * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation * -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeArgs.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeArgs.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeArgs.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeArgs.sh 2020-01-13 05:52:26.000000000 +0000 @@ -52,6 +52,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} @@ -64,7 +72,7 @@ ${TESTSRC}${FS}libTestCriticalNative.c # run the java test in the background -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeArgs" echo "$cmd" @@ -76,7 +84,7 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeArgs" echo "$cmd" @@ -104,6 +112,30 @@ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeArgs" echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -Xcomp -Xmx256M -XX:+CriticalJNINatives \ + -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeArgs" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives \ + -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeArgs" + +echo "$cmd" eval $cmd if [ $? -ne 0 ] diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeStress.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeStress.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeStress.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestCriticalNativeStress.sh 2020-01-13 05:52:26.000000000 +0000 @@ -52,6 +52,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} @@ -65,7 +73,7 @@ # run the java test in the background -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeStress" echo "$cmd" @@ -77,7 +85,7 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives \ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeStress" echo "$cmd" @@ -105,6 +113,30 @@ -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeStress" echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -Xcomp -Xmx256M -XX:+CriticalJNINatives \ + -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeStress" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives \ + -Djava.library.path=${THIS_DIR}${FS} TestCriticalNativeStress" + +echo "$cmd" eval $cmd if [ $? -ne 0 ] diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNICritical.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNICritical.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNICritical.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNICritical.sh 2020-01-13 05:52:26.000000000 +0000 @@ -51,6 +51,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNIGlobalRefs.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNIGlobalRefs.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNIGlobalRefs.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestJNIGlobalRefs.sh 2020-01-13 05:52:26.000000000 +0000 @@ -51,6 +51,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} @@ -87,7 +95,7 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahVerify \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahVerify \ -Djava.library.path=${THIS_DIR}${FS} TestJNIGlobalRefs" echo "$cmd" @@ -99,7 +107,7 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive \ +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive \ -Djava.library.path=${THIS_DIR}${FS} TestJNIGlobalRefs" echo "$cmd" diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestPinnedGarbage.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestPinnedGarbage.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jni/TestPinnedGarbage.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jni/TestPinnedGarbage.sh 2020-01-13 05:52:26.000000000 +0000 @@ -51,6 +51,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} @@ -63,7 +71,7 @@ ${TESTSRC}${FS}libTestPinnedGarbage.c # run the java test in the background -cmd="${TESTJAVA}${FS}bin${FS}java -Xmx512m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC -XX:ShenandoahGCHeuristics=passive \ +cmd="${TESTJAVA}${FS}bin${FS}java -Xmx512m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC -XX:ShenandoahGCMode=passive \ -Djava.library.path=${THIS_DIR}${FS} TestPinnedGarbage" echo "$cmd" @@ -75,7 +83,7 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -Xmx512m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC -XX:ShenandoahGCHeuristics=passive \ +cmd="${TESTJAVA}${FS}bin${FS}java -Xmx512m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC -XX:ShenandoahGCMode=passive \ -Djava.library.path=${THIS_DIR}${FS} TestPinnedGarbage" echo "$cmd" diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/libTestGetLoadedClasses.c openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/libTestGetLoadedClasses.c --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/libTestGetLoadedClasses.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/libTestGetLoadedClasses.c 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include +#include +#include "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +static const char *EXC_CNAME = "java/lang/Exception"; + +static jvmtiEnv *jvmti = NULL; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_1_8; +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jvmtiCapabilities capabilities; + jint res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + (void)memset(&capabilities, 0, sizeof(capabilities)); + capabilities.can_tag_objects = 1; + capabilities.can_generate_garbage_collection_events = 1; + (*jvmti)->AddCapabilities(jvmti, &capabilities); + + return JNI_OK; +} + +static +void throw_exc(JNIEnv *env, char *msg) { + jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME)); + jint rt = JNI_OK; + + if (exc_class == NULL) { + printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME); + return; + } + rt = JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); + if (rt == JNI_ERR) { + printf("throw_exc: Error in JNI ThrowNew(env, %s)\n", msg); + } +} + +JNIEXPORT jint JNICALL +Java_TestGetLoadedClasses_getLoadedClasses(JNIEnv *env, jclass cls) { + jint totalCount = 0; + jclass* classes; + if (jvmti == NULL) { + throw_exc(env, "JVMTI client was not properly loaded!\n"); + return 0; + } + + (*jvmti)->GetLoadedClasses(jvmti, &totalCount, &classes); + (*jvmti)->Deallocate(jvmti, (unsigned char*)classes); + return totalCount; +} + +#ifdef __cplusplus +} +#endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.io.*; +import java.nio.file.*; + +public class TestGetLoadedClasses { + + private static final int NUM_ITER = 1000; + private static final int NUM_CLASSES = 10000; + + static { + try { + System.loadLibrary("TestGetLoadedClasses"); + } catch (UnsatisfiedLinkError ule) { + System.err.println("Could not load TestGetLoadedClasses library"); + System.err.println("java.library.path: " + + System.getProperty("java.library.path")); + throw ule; + } + } + + native static int getLoadedClasses(); + + static Class[] classes = new Class[NUM_CLASSES]; + + static class Dummy { + } + + static class MyClassLoader extends ClassLoader { + final String path; + + MyClassLoader(String path) { + this.path = path; + } + + public Class loadClass(String name) throws ClassNotFoundException { + try { + File f = new File(path, name + ".class"); + if (!f.exists()) { + return super.loadClass(name); + } + + Path path = Paths.get(f.getAbsolutePath()); + byte[] cls = Files.readAllBytes(path); + return defineClass(name, cls, 0, cls.length, null); + } catch (IOException e) { + throw new ClassNotFoundException(name); + } + } + } + + static Class load(String path) throws Exception { + ClassLoader cl = new MyClassLoader(path); + Class c = (Class) Class.forName("TestGetLoadedClasses$Dummy", true, cl); + if (c.getClassLoader() != cl) { + throw new IllegalStateException("Should have loaded by target loader"); + } + return c; + } + + static void loadClasses() throws Exception { + String classDir = TestGetLoadedClasses.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + for (int c = 0; c < NUM_CLASSES; c++) { + classes[c] = load(classDir); + } + } + + public static void main(String args[]) throws Exception { + loadClasses(); + new TestGetLoadedClasses().run(); + } + + volatile Object sink; + public void run() throws Exception { + for (int i = 0; i < NUM_ITER; i++) { + sink = new byte[1000000]; + int count = getLoadedClasses(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.sh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestGetLoadedClasses.sh 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,102 @@ +#!/bin/sh + +# +# Copyright (c) 2019, Red Hat, Inc. All rights reserved. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +## +## @test +## @summary test JVMTI GetLoadedClasses in Shenandoah +## @run shell/timeout=480 TestGetLoadedClasses.sh +## + +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../../test_env.sh + +# set platform-dependent variables +if [ "$VM_OS" = "linux" ]; then + echo "Testing on linux" + gcc_cmd=`which gcc` + if [ "x$gcc_cmd" = "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi +else + echo "Test passed; only valid for linux: $VM_OS" + exit 0; +fi + +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + +THIS_DIR=. + +cp ${TESTSRC}${FS}*.java ${THIS_DIR} +${TESTJAVA}${FS}bin${FS}javac TestGetLoadedClasses.java + +$gcc_cmd -O1 -DLINUX -fPIC -shared \ + -o ${THIS_DIR}${FS}libTestGetLoadedClasses.so \ + -I${TESTJAVA}${FS}include \ + -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}libTestGetLoadedClasses.c + +# run the java test in the background +cmd="${TESTJAVA}${FS}bin${FS}java -agentpath:./libTestGetLoadedClasses.so -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC \ + -XX:ShenandoahSATBBufferSize=1 -XX:+ClassUnloadingWithConcurrentMark -XX:+ClassUnloading -Djava.library.path=${THIS_DIR}${FS} TestGetLoadedClasses" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +if [ "$VM_BITS" = "64" ]; then + cmd="${TESTJAVA}${FS}bin${FS}java -agentpath:./libTestGetLoadedClasses.so -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC \ + -XX:ShenandoahSATBBufferSize=1 -XX:+ClassUnloadingWithConcurrentMark -XX:+ClassUnloading -XX:-UseCompressedOops -Djava.library.path=${THIS_DIR}${FS} TestGetLoadedClasses" + + echo "$cmd" + eval $cmd + + if [ $? -ne 0 ] + then + echo "Test Failed" + exit 1 + fi +else + echo "Test passed; only valid for 64 bits" + exit 0; +fi diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestHeapDump.sh openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestHeapDump.sh --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestHeapDump.sh 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/jvmti/TestHeapDump.sh 2020-01-13 05:52:26.000000000 +0000 @@ -52,6 +52,14 @@ exit 0; fi +# Unfortunately, configurations cross-compiled to 32 bits would +# fail with bitness mismatch, when compiled with platform gcc. +# This would be fixed with /native support in JDK-8072842. +if [ "$VM_BITS" = "32" ]; then + echo "Test passed; only reliable on 64-bit" + exit 0; +fi + THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} @@ -65,7 +73,7 @@ # run the java test in the background cmd="${TESTJAVA}${FS}bin${FS}java -agentpath:./libTestHeapDump.so -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive \ - -XX:+UseCompressedOops -Djava.library.path=${THIS_DIR}${FS} TestHeapDump" + -Djava.library.path=${THIS_DIR}${FS} TestHeapDump" echo "$cmd" eval $cmd @@ -76,14 +84,19 @@ exit 1 fi -cmd="${TESTJAVA}${FS}bin${FS}java -agentpath:./libTestHeapDump.so -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive \ - -XX:-UseCompressedOops -Djava.library.path=${THIS_DIR}${FS} TestHeapDump" - -echo "$cmd" -eval $cmd - -if [ $? -ne 0 ] -then - echo "Test Failed" - exit 1 +if [ "$VM_BITS" = "64" ]; then + cmd="${TESTJAVA}${FS}bin${FS}java -agentpath:./libTestHeapDump.so -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive \ + -XX:-UseCompressedOops -Djava.library.path=${THIS_DIR}${FS} TestHeapDump" + + echo "$cmd" + eval $cmd + + if [ $? -ne 0 ] + then + echo "Test Failed" + exit 1 + fi +else + echo "Test passed; only valid for 64 bits" + exit 0; fi diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestChurnNotifications.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestChurnNotifications.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestChurnNotifications.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestChurnNotifications.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,13 +26,16 @@ * @summary Check that MX notifications are reported for all cycles * @key gc * - * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications - * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications * * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -Dprecise=false TestChurnNotifications * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static -Dprecise=false TestChurnNotifications * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact -Dprecise=false TestChurnNotifications * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Dprecise=false TestChurnNotifications + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Dprecise=false TestChurnNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -Dprecise=false TestChurnNotifications */ import java.util.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestPauseNotifications.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestPauseNotifications.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestPauseNotifications.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/mxbeans/TestPauseNotifications.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,14 +26,17 @@ * @summary Check that MX notifications are reported for all cycles * @key gc * - * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestPauseNotifications - * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestPauseNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestPauseNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestPauseNotifications * * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive TestPauseNotifications * * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive TestPauseNotifications * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static TestPauseNotifications * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact TestPauseNotifications + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestPauseNotifications + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal TestPauseNotifications */ import java.util.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/oom/TestClassLoaderLeak.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/oom/TestClassLoaderLeak.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/oom/TestClassLoaderLeak.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/oom/TestClassLoaderLeak.java 2020-01-13 05:52:26.000000000 +0000 @@ -122,29 +122,31 @@ return; } - String[] heuristics = new String[] { - "adaptive", - "compact", - "static", - "aggressive", - "passive", + String[][][] modeHeuristics = new String[][][] { + {{"normal"}, {"adaptive", "compact", "static", "aggressive"}}, + {{"traversal"}, {"adaptive", "aggressive"}}, + {{"passive"}, {"passive"}} }; - for (String h : heuristics) { - // Forceful enabling should work - passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading"); - passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloadingWithConcurrentMark"); + for (String[][] mh : modeHeuristics) { + String mode = mh[0][0]; + String[] heuristics = mh[1]; + for (String h : heuristics) { + // Forceful enabling should work + passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading"); + passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloadingWithConcurrentMark"); - // Even when concurrent unloading is disabled, Full GC has to recover - passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark"); - passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0"); - passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0"); + // Even when concurrent unloading is disabled, Full GC has to recover + passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark"); + passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0"); + passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0"); - // Should OOME when unloading forcefully disabled, even if local flags try to enable it back - failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading"); - failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark"); - failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1"); - failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1"); + // Should OOME when unloading forcefully disabled, even if local flags try to enable it back + failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading"); + failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark"); + failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1"); + failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1"); + } } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/oom/TestThreadFailure.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/oom/TestThreadFailure.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/oom/TestThreadFailure.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/oom/TestThreadFailure.java 2020-01-13 05:52:26.000000000 +0000 @@ -61,21 +61,7 @@ { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-Xmx16m", - "-XX:+UnlockExperimentalVMOptions", - "-XX:+UseShenandoahGC", - TestThreadFailure.class.getName(), - "test"); - - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); - analyzer.shouldHaveExitValue(0); - analyzer.shouldContain("java.lang.OutOfMemoryError"); - analyzer.shouldContain("All good"); - } - - { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-Xmx128m", + "-Xmx64m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestThreadFailure.class.getName(), diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestExplicitGC.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestExplicitGC.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestExplicitGC.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestExplicitGC.java 2020-01-13 05:52:26.000000000 +0000 @@ -1,4 +1,4 @@ -/* +'/* * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it @@ -51,11 +51,16 @@ "Pause Full" }; - String[] concurrent = new String[] { + String[] concNormal = new String[] { "Pause Init Mark", "Pause Final Mark", }; + String[] concTraversal = new String[] { + "Pause Init Traversal", + "Pause Final Traversal", + }; + { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockExperimentalVMOptions", @@ -67,9 +72,12 @@ for (String p : full) { output.shouldNotContain(p); } - for (String p : concurrent) { + for (String p : concNormal) { output.shouldContain(p); } + for (String p : concTraversal) { + output.shouldNotContain(p); + } } { @@ -84,7 +92,10 @@ for (String p : full) { output.shouldNotContain(p); } - for (String p : concurrent) { + for (String p : concNormal) { + output.shouldNotContain(p); + } + for (String p : concTraversal) { output.shouldNotContain(p); } } @@ -101,9 +112,12 @@ for (String p : full) { output.shouldNotContain(p); } - for (String p : concurrent) { + for (String p : concNormal) { output.shouldContain(p); } + for (String p : concTraversal) { + output.shouldNotContain(p); + } } { @@ -111,6 +125,27 @@ "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-verbose:gc", + "-XX:+ExplicitGCInvokesConcurrent", + "-XX:ShenandoahGCMode=traversal", + TestExplicitGC.class.getName(), + "test"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + for (String p : full) { + output.shouldNotContain(p); + } + for (String p : concNormal) { + output.shouldNotContain(p); + } + for (String p : concTraversal) { + output.shouldContain(p); + } + } + + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-verbose:gc", "-XX:-ExplicitGCInvokesConcurrent", TestExplicitGC.class.getName(), "test"); @@ -118,7 +153,10 @@ for (String p : full) { output.shouldContain(p); } - for (String p : concurrent) { + for (String p : concNormal) { + output.shouldNotContain(p); + } + for (String p : concTraversal) { output.shouldNotContain(p); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestHeuristicsUnlock.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestHeuristicsUnlock.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestHeuristicsUnlock.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestHeuristicsUnlock.java 2020-01-13 05:52:26.000000000 +0000 @@ -41,12 +41,14 @@ } public static void main(String[] args) throws Exception { - testWith("adaptive", Mode.PRODUCT); - testWith("static", Mode.PRODUCT); - testWith("compact", Mode.PRODUCT); + testWith("-XX:ShenandoahGCHeuristics=adaptive", Mode.PRODUCT); + testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT); + testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT); - testWith("aggressive", Mode.DIAGNOSTIC); - testWith("passive", Mode.DIAGNOSTIC); + testWith("-XX:ShenandoahGCMode=traversal", Mode.PRODUCT); + + testWith("-XX:ShenandoahGCHeuristics=aggressive", Mode.DIAGNOSTIC); + testWith("-XX:ShenandoahGCMode=passive", Mode.DIAGNOSTIC); } private static void testWith(String h, Mode mode) throws Exception { @@ -55,7 +57,7 @@ "-XX:-UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, + h, "-version" ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); @@ -75,7 +77,7 @@ "-XX:+UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, + h, "-version" ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); @@ -95,7 +97,7 @@ "-XX:-UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, + h, "-version" ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestHumongousMoves.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestHumongousMoves.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestHumongousMoves.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestHumongousMoves.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test TestHumongousMoves + * @summary Check Shenandoah reacts on setting humongous moves correctly + * @key gc + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive + * -XX:-ShenandoahHumongousMoves + * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify + * TestHumongousMoves + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive + * -XX:+ShenandoahHumongousMoves + * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify + * TestHumongousMoves + */ + +import java.util.Random; + +public class TestHumongousMoves { + + static final long TARGET_MB = Long.getLong("target", 10_000); // 10 Gb allocation + + static volatile Object sink; + + public static void main(String[] args) throws Exception { + final int min = 0; + final int max = 384 * 1024; + long count = TARGET_MB * 1024 * 1024 / (16 + 4 * (min + (max - min) / 2)); + + Random r = new Random(); + for (long c = 0; c < count; c++) { + sink = new int[min + r.nextInt(max - min)]; + } + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestObjectAlignment.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestObjectAlignment.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestObjectAlignment.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestObjectAlignment.java 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,21 @@ * @test TestObjectAlignment * @key gc * + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx32m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx64m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx128m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx256m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx512m TestObjectAlignment + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g TestObjectAlignment + */ + +/* + * @test TestObjectAlignment + * @key gc + * @requires (vm.bits == "64") + * * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 TestObjectAlignment * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -Xmx16m TestObjectAlignment * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -Xmx32m TestObjectAlignment diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java 2020-01-13 05:52:26.000000000 +0000 @@ -41,10 +41,8 @@ public static void main(String[] args) throws Exception { String[][] opts = { new String[]{ "ShenandoahSATBBarrier" }, - new String[]{ "ShenandoahWriteBarrier" }, - new String[]{ "ShenandoahReadBarrier" }, + new String[]{ "ShenandoahLoadRefBarrier" }, new String[]{ "ShenandoahCASBarrier" }, - new String[]{ "ShenandoahAcmpBarrier" }, new String[]{ "ShenandoahCloneBarrier" }, }; @@ -64,7 +62,7 @@ conf.add("-XX:+UnlockDiagnosticVMOptions"); conf.add("-XX:+UnlockExperimentalVMOptions"); conf.add("-XX:+UseShenandoahGC"); - conf.add("-XX:ShenandoahGCHeuristics=passive"); + conf.add("-XX:ShenandoahGCMode=passive"); StringBuilder sb = new StringBuilder(); for (String[] l : opts) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCounts.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCounts.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCounts.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCounts.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test TestThreadCounts + * @summary Test that Shenandoah GC thread counts are handled well + * @key gc + * @library /testlibrary + * @run driver TestThreadCounts + */ + +import com.oracle.java.testlibrary.*; + +public class TestThreadCounts { + public static void main(String[] args) throws Exception { + for (int conc = 0; conc < 16; conc++) { + for (int par = 0; par < 16; par++) { + testWith(conc, par); + } + } + } + + private static void testWith(int conc, int par) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ConcGCThreads=" + conc, + "-XX:ParallelGCThreads=" + par, + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + if (conc == 0) { + output.shouldContain("Shenandoah expects ConcGCThreads > 0"); + output.shouldHaveExitValue(1); + } else if (par == 0) { + output.shouldContain("Shenandoah expects ParallelGCThreads > 0"); + output.shouldHaveExitValue(1); + } else if (conc > par) { + output.shouldContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads"); + output.shouldHaveExitValue(1); + } else { + output.shouldNotContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads"); + output.shouldHaveExitValue(0); + } + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCountsOverride.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCountsOverride.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCountsOverride.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestThreadCountsOverride.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test TestThreadCountsOverride + * @summary Test that Shenandoah GC thread counts are overridable + * @key gc + * @library /testlibrary + * @run driver TestThreadCountsOverride + */ + +import com.oracle.java.testlibrary.*; + +public class TestThreadCountsOverride { + public static void main(String[] args) throws Exception { + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ParallelGCThreads=1", + "-XX:+PrintFlagsFinal", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldMatch("ParallelGCThreads(.*)= 1 "); + output.shouldHaveExitValue(0); + } + + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ConcGCThreads=1", + "-XX:+PrintFlagsFinal", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldMatch("ConcGCThreads(.*)= 1 "); + output.shouldHaveExitValue(0); + } + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestWrongBarrierDisable.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestWrongBarrierDisable.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/options/TestWrongBarrierDisable.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/options/TestWrongBarrierDisable.java 2020-01-13 05:52:26.000000000 +0000 @@ -36,19 +36,26 @@ public static void main(String[] args) throws Exception { String[] concurrent = { - "ShenandoahReadBarrier", - "ShenandoahWriteBarrier", + "ShenandoahLoadRefBarrier", "ShenandoahCASBarrier", - "ShenandoahAcmpBarrier", "ShenandoahCloneBarrier", "ShenandoahSATBBarrier", + "ShenandoahKeepAliveBarrier", }; - shouldFailAll("adaptive", concurrent); - shouldFailAll("static", concurrent); - shouldFailAll("compact", concurrent); - shouldFailAll("aggressive", concurrent); - shouldPassAll("passive", concurrent); + String[] traversal = { + "ShenandoahLoadRefBarrier", + "ShenandoahCASBarrier", + "ShenandoahCloneBarrier", + }; + + shouldFailAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=static", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=compact", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=aggressive", concurrent); + shouldFailAll("-XX:ShenandoahGCMode=traversal", traversal); + shouldPassAll("-XX:ShenandoahGCMode=passive", concurrent); + shouldPassAll("-XX:ShenandoahGCMode=passive", traversal); } private static void shouldFailAll(String h, String[] barriers) throws Exception { @@ -57,7 +64,7 @@ "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, + h, "-XX:-" + b, "-version" ); @@ -74,7 +81,7 @@ "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, + h, "-XX:-" + b, "-version" ); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocHumongousFragment.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocHumongousFragment.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocHumongousFragment.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocHumongousFragment.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Make sure Shenandoah can recover from humongous allocation fragmentation * @key gc * - * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment - * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment - * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocHumongousFragment - * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestAllocHumongousFragment * * @run main/othervm/timeout=240 -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocHumongousFragment * @run main/othervm/timeout=240 -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocHumongousFragment @@ -41,6 +41,13 @@ * * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=adaptive TestAllocHumongousFragment * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=static TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestAllocHumongousFragment + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCMode=traversal TestAllocHumongousFragment */ import java.util.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocIntArrays.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocIntArrays.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocIntArrays.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocIntArrays.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Acceptance tests: collector can withstand allocation * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocIntArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestAllocIntArrays * * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocIntArrays * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocIntArrays @@ -44,6 +44,14 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocIntArrays * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocIntArrays * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestAllocIntArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal TestAllocIntArrays + * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestAllocIntArrays */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjectArrays.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjectArrays.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjectArrays.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjectArrays.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Acceptance tests: collector can withstand allocation * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocObjectArrays - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestAllocObjectArrays * * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjectArrays * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjectArrays @@ -44,6 +44,14 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocObjectArrays * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocObjectArrays * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestAllocObjectArrays + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal TestAllocObjectArrays + * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestAllocObjectArrays */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjects.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjects.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjects.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestAllocObjects.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Acceptance tests: collector can withstand allocation * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestAllocObjects * * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjects * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjects @@ -43,6 +43,14 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestAllocObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocObjects + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestAllocObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal TestAllocObjects */ import java.util.Random; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestEvilSyncBug.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestEvilSyncBug.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestEvilSyncBug.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestEvilSyncBug.java 2020-01-13 05:52:26.000000000 +0000 @@ -58,7 +58,6 @@ "-XX:+UnlockDiagnosticVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahGCHeuristics=aggressive", - "-XX:+ShenandoahStoreCheck", "TestEvilSyncBug", "test"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestGCThreadGroups.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestGCThreadGroups.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestGCThreadGroups.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestGCThreadGroups.java 2020-01-13 05:52:26.000000000 +0000 @@ -29,16 +29,14 @@ * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -Dtarget=1000 TestGCThreadGroups * @run main/othervm -XX:-UseDynamicNumberOfGCThreads -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -Dtarget=1000 TestGCThreadGroups * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ForceDynamicNumberOfGCThreads -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -Dtarget=1000 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=1000 TestGCThreadGroups + * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=passive -Dtarget=1000 TestGCThreadGroups * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=1000 TestGCThreadGroups * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=1000 TestGCThreadGroups * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=100 TestGCThreadGroups * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=100 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=1000 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=1000 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=1000 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=100 TestGCThreadGroups - * @run main/othervm -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=100 TestGCThreadGroups + * + * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -Dtarget=100 TestGCThreadGroups + * @run main/othervm -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Dtarget=100 TestGCThreadGroups */ public class TestGCThreadGroups { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestHeapUncommit.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestHeapUncommit.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestHeapUncommit.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestHeapUncommit.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,19 +26,24 @@ * @summary Acceptance tests: collector can withstand allocation * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=passive -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=passive -XX:ShenandoahUncommitDelay=0 -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=passive -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=passive -XX:ShenandoahUncommitDelay=0 -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=adaptive -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=static -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=compact -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=passive -XX:ShenandoahUncommitDelay=0 TestHeapUncommit + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=passive -XX:ShenandoahUncommitDelay=0 TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=adaptive -XX:ShenandoahUncommitDelay=0 TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=static -XX:ShenandoahUncommitDelay=0 TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=compact -XX:ShenandoahUncommitDelay=0 TestHeapUncommit * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUncommitDelay=0 TestHeapUncommit + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=traversal -XX:ShenandoahUncommitDelay=0 TestHeapUncommit + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=traversal -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUncommitDelay=0 TestHeapUncommit + * */ import java.util.Random; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestHumongousThreshold.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestHumongousThreshold.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestHumongousThreshold.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestHumongousThreshold.java 2020-01-13 05:52:26.000000000 +0000 @@ -58,6 +58,19 @@ * TestHumongousThreshold * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g + * -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive + * TestHumongousThreshold + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g + * -XX:-UseTLAB -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive + * TestHumongousThreshold + */ + +/* + * @test TestHumongousThreshold + * @key gc + * @requires (vm.bits == "64") + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify * TestHumongousThreshold * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g @@ -88,13 +101,6 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=100 * TestHumongousThreshold - * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g - * -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive - * TestHumongousThreshold - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g - * -XX:-UseTLAB -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive - * TestHumongousThreshold */ import java.util.Random; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestLargeObjectAlignment.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestLargeObjectAlignment.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestLargeObjectAlignment.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestLargeObjectAlignment.java 2020-01-13 05:52:26.000000000 +0000 @@ -25,6 +25,7 @@ * @test TestLargeObjectAlignment * @summary Shenandoah crashes with -XX:ObjectAlignmentInBytes=16 * @key gc + * @requires (vm.bits == "64") * * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -Xint TestLargeObjectAlignment * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:-TieredCompilation TestLargeObjectAlignment diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestLotsOfCycles.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestLotsOfCycles.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestLotsOfCycles.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestLotsOfCycles.java 2020-01-13 05:52:26.000000000 +0000 @@ -25,8 +25,8 @@ * @test TestLotsOfCycles * @key gc * - * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=10000 -XX:+ShenandoahDegeneratedGC TestLotsOfCycles - * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=10000 -XX:-ShenandoahDegeneratedGC TestLotsOfCycles + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=passive -Dtarget=10000 -XX:+ShenandoahDegeneratedGC TestLotsOfCycles + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=passive -Dtarget=10000 -XX:-ShenandoahDegeneratedGC TestLotsOfCycles * * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 -XX:+ShenandoahOOMDuringEvacALot TestLotsOfCycles * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 -XX:+ShenandoahAllocFailureALot TestLotsOfCycles @@ -35,6 +35,11 @@ * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=10000 TestLotsOfCycles * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=10000 TestLotsOfCycles * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=1000 TestLotsOfCycles + * + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -Dtarget=1000 TestLotsOfCycles + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -Dtarget=1000 TestLotsOfCycles + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 TestLotsOfCycles + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCMode=traversal -Dtarget=1000 TestLotsOfCycles */ public class TestLotsOfCycles { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestPeriodicGC.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestPeriodicGC.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestPeriodicGC.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestPeriodicGC.java 2020-01-13 05:52:26.000000000 +0000 @@ -64,11 +64,6 @@ "static" }; - String[] disabled = new String[] { - "aggressive", - "passive", - }; - for (String h : enabled) { testWith("Short period with " + h, true, @@ -91,17 +86,44 @@ ); } - for (String h : disabled) { - testWith("Short period with " + h, - false, - "-verbose:gc", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+UnlockExperimentalVMOptions", - "-XX:+UseShenandoahGC", - "-XX:ShenandoahGCHeuristics=" + h, - "-XX:ShenandoahGuaranteedGCInterval=1000" - ); - } + testWith("Short period with traversal mode", + true, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=traversal", + "-XX:ShenandoahGuaranteedGCInterval=1000" + ); + + testWith("Long period with traversal mode", + false, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=traversal", + "-XX:ShenandoahGuaranteedGCInterval=100000" // deliberately too long + ); + + testWith("Short period with aggressive", + false, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCHeuristics=aggressive", + "-XX:ShenandoahGuaranteedGCInterval=1000" + ); + testWith("Short period with passive", + false, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=passive", + "-XX:ShenandoahGuaranteedGCInterval=1000" + ); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRefprocSanity.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRefprocSanity.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRefprocSanity.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRefprocSanity.java 2020-01-13 05:52:26.000000000 +0000 @@ -29,6 +29,10 @@ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestRefprocSanity * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahVerify TestRefprocSanity * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive TestRefprocSanity + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal TestRefprocSanity + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestRefprocSanity + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestRefprocSanity */ import java.lang.ref.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRegionSampling.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRegionSampling.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRegionSampling.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRegionSampling.java 2020-01-13 05:52:26.000000000 +0000 @@ -31,8 +31,11 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact -XX:+ShenandoahRegionSampling TestRegionSampling * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahRegionSampling TestRegionSampling * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahRegionSampling TestRegionSampling + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahRegionSampling TestRegionSampling */ public class TestRegionSampling { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRetainObjects.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRetainObjects.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestRetainObjects.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestRetainObjects.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Acceptance tests: collector can deal with retained objects * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestRetainObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestRetainObjects * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestRetainObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestRetainObjects @@ -42,6 +42,12 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=static TestRetainObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCHeuristics=compact TestRetainObjects * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestRetainObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:ShenandoahGCMode=traversal TestRetainObjects + * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xms1g -Xmx1g -XX:-UseTLAB TestRetainObjects */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestSieveObjects.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestSieveObjects.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestSieveObjects.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestSieveObjects.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Acceptance tests: collector can deal with retained objects * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestSieveObjects - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestSieveObjects * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestSieveObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestSieveObjects @@ -42,6 +42,12 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestSieveObjects * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestSieveObjects * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestSieveObjects + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCMode=traversal TestSieveObjects + * * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestSieveObjects */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringDedup.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringDedup.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringDedup.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringDedup.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,12 +26,15 @@ * @summary Test Shenandoah string deduplication implementation * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M TestStringDedup - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M TestStringDedup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M TestStringDedup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M TestStringDedup * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx256M TestStringDedup * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+UseStringDeduplication -Xmx256M TestStringDedup * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact -XX:+UseStringDeduplication -Xmx256M TestStringDedup + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -XX:+UseStringDeduplication -Xmx256M TestStringDedup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:+UseStringDeduplication -Xmx256M TestStringDedup */ import java.lang.reflect.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringDedupStress.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringDedupStress.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringDedupStress.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringDedupStress.java 2020-01-13 05:52:26.000000000 +0000 @@ -51,12 +51,12 @@ * TestStringDedupStress * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g - * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -DtargetOverwrites=40000000 + * -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -DtargetOverwrites=40000000 * -verbose:gc * TestStringDedupStress * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g - * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -DtargetOverwrites=40000000 + * -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -DtargetOverwrites=40000000 * -verbose:gc * TestStringDedupStress * @@ -84,6 +84,30 @@ * -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUpdateRefsEarly=off -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000 * -verbose:gc * TestStringDedupStress + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g + * -XX:ShenandoahGCMode=traversal + * -verbose:gc + * TestStringDedupStress + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g + * -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -DtargetStrings=2000000 + * -verbose:gc + * TestStringDedupStress + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g + * -XX:ShenandoahGCMode=traversal + * -XX:+ShenandoahOOMDuringEvacALot + * -DtargetStrings=2000000 + * -verbose:gc + * TestStringDedupStress + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g + * -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * -DtargetStrings=2000000 + * -verbose:gc + * TestStringDedupStress */ import java.lang.management.*; diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringInternCleanup.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringInternCleanup.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestStringInternCleanup.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestStringInternCleanup.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,10 +26,10 @@ * @summary Check that Shenandoah cleans up interned strings * @key gc * - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestStringInternCleanup - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC TestStringInternCleanup * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=aggressive TestStringInternCleanup @@ -40,6 +40,10 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=static TestStringInternCleanup * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=compact TestStringInternCleanup * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=traversal -XX:+ShenandoahVerify -XX:ShenandoahGCHeuristics=aggressive TestStringInternCleanup + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCMode=traversal TestStringInternCleanup + * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:-ClassUnloadingWithConcurrentMark -Xmx64m TestStringInternCleanup */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestVerifyJCStress.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestVerifyJCStress.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestVerifyJCStress.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestVerifyJCStress.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,28 +26,34 @@ * @summary Tests that we pass at least one jcstress-like test with all verification turned on * @key gc * - * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions + * @run main/othervm -Xmx1g -Xms1g * -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC - * -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals - * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC + * -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC + * -XX:+ShenandoahVerify * TestVerifyJCStress * - * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions + * @run main/othervm -Xmx1g -Xms1g * -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC - * -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals - * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC + * -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC + * -XX:+ShenandoahVerify * TestVerifyJCStress * - * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions + * @run main/othervm -Xmx1g -Xms1g * -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC - * -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers * -XX:ShenandoahGCHeuristics=adaptive + * -XX:+ShenandoahVerify -XX:+IgnoreUnrecognizedVMOptions -XX:+ShenandoahVerifyOptoBarriers * TestVerifyJCStress * - * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions + * @run main/othervm -Xmx1g -Xms1g * -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC - * -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers * -XX:ShenandoahGCHeuristics=static + * -XX:+ShenandoahVerify -XX:+IgnoreUnrecognizedVMOptions -XX:+ShenandoahVerifyOptoBarriers + * TestVerifyJCStress + * + * @run main/othervm -Xmx1g -Xms1g + * -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC + * -XX:ShenandoahGCMode=traversal + * -XX:+ShenandoahVerify -XX:+IgnoreUnrecognizedVMOptions -XX:+ShenandoahVerifyOptoBarriers * TestVerifyJCStress */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestWrongArrayMember.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestWrongArrayMember.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/shenandoah/TestWrongArrayMember.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/shenandoah/TestWrongArrayMember.java 2020-01-13 05:52:26.000000000 +0000 @@ -26,6 +26,7 @@ * @key gc * * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestWrongArrayMember + * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal TestWrongArrayMember */ public class TestWrongArrayMember { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 2020-01-13 05:52:26.000000000 +0000 @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package gc.stress.gclocker; + +// Based on Kim Barrett;s test for JDK-8048556 + +/* + * @test TestExcessGCLockerCollections + * @key gc + * @bug 8048556 + * @summary Check for GC Locker initiated GCs that immediately follow another + * GC and so have very little needing to be collected. + * @library /testlibrary + * @run driver/timeout=1000 gc.stress.gclocker.TestExcessGCLockerCollections 300 4 2 + */ + +import java.util.HashMap; +import java.util.Map; + +import java.util.zip.Deflater; + +import java.util.ArrayList; +import java.util.Arrays; + +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; +import java.lang.management.ManagementFactory; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import com.sun.management.GarbageCollectionNotificationInfo; +import com.sun.management.GcInfo; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +class TestExcessGCLockerCollectionsStringConstants { + // Some constant strings used in both GC logging and error detection + static public final String GCLOCKER_CAUSE = "GCLocker Initiated GC"; + static public final String USED_TOO_LOW = "TOO LOW"; + static public final String USED_OK = "OK"; +} + +class TestExcessGCLockerCollectionsAux { + static private final int LARGE_MAP_SIZE = 64 * 1024; + + static private final int MAP_ARRAY_LENGTH = 4; + static private final int MAP_SIZE = 1024; + + static private final int BYTE_ARRAY_LENGTH = 128 * 1024; + + static private void println(String str) { System.out.println(str); } + static private void println() { System.out.println(); } + + static private volatile boolean keepRunning = true; + + static Map populateMap(int size) { + Map map = new HashMap(); + for (int i = 0; i < size; i += 1) { + Integer keyInt = Integer.valueOf(i); + String valStr = "value is [" + i + "]"; + map.put(keyInt,valStr); + } + return map; + } + + static private class AllocatingWorker implements Runnable { + private final Object[] array = new Object[MAP_ARRAY_LENGTH]; + private int arrayIndex = 0; + + private void doStep() { + Map map = populateMap(MAP_SIZE); + array[arrayIndex] = map; + arrayIndex = (arrayIndex + 1) % MAP_ARRAY_LENGTH; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static private class JNICriticalWorker implements Runnable { + private int count; + + private void doStep() { + byte[] inputArray = new byte[BYTE_ARRAY_LENGTH]; + for (int i = 0; i < inputArray.length; i += 1) { + inputArray[i] = (byte) (count + i); + } + + Deflater deflater = new Deflater(); + deflater.setInput(inputArray); + deflater.finish(); + + byte[] outputArray = new byte[2 * inputArray.length]; + deflater.deflate(outputArray); + + count += 1; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static class GCNotificationListener implements NotificationListener { + static private final double MIN_USED_PERCENT = 40.0; + + static private final List newGenPoolNames = Arrays.asList( + "G1 Eden Space", // OpenJDK G1GC: -XX:+UseG1GC + "PS Eden Space", // OpenJDK ParallelGC: -XX:+ParallelGC + "Par Eden Space", // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC + "Eden Space" // OpenJDK SerialGC: -XX:+UseSerialGC + // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC -XX:-UseParNewGC + ); + + @Override + public void handleNotification(Notification notification, Object handback) { + try { + if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + GarbageCollectionNotificationInfo info = + GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + + String gc_cause = info.getGcCause(); + + if (gc_cause.equals(TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE)) { + Map memory_before_gc = info.getGcInfo().getMemoryUsageBeforeGc(); + + for (String newGenPoolName : newGenPoolNames) { + MemoryUsage usage = memory_before_gc.get(newGenPoolName); + if (usage == null) continue; + + double startTime = ((double) info.getGcInfo().getStartTime()) / 1000.0; + long used = usage.getUsed(); + long committed = usage.getCommitted(); + long max = usage.getMax(); + double used_percent = (((double) used) / Math.max(committed, max)) * 100.0; + + System.out.printf("%6.3f: (%s) %d/%d/%d, %8.4f%% (%s)\n", + startTime, gc_cause, used, committed, max, used_percent, + ((used_percent < MIN_USED_PERCENT) ? TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + : TestExcessGCLockerCollectionsStringConstants.USED_OK)); + } + } + } + } catch (RuntimeException ex) { + System.err.println("Exception during notification processing:" + ex); + ex.printStackTrace(); + } + } + + public static boolean register() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + + // Get the list of MX + List gc_mxbeans = ManagementFactory.getGarbageCollectorMXBeans(); + + // Create the notification listener + GCNotificationListener gcNotificationListener = new GCNotificationListener(); + + for (GarbageCollectorMXBean gcbean : gc_mxbeans) { + // Add notification listener for the MXBean + mbeanServer.addNotificationListener(gcbean.getObjectName(), gcNotificationListener, null, null); + } + } catch (Exception ex) { + System.err.println("Exception during mbean registration:" + ex); + ex.printStackTrace(); + // We've failed to set up, terminate + return false; + } + + return true; + } + } + + static public Map largeMap; + + static public void main(String args[]) { + long durationSec = Long.parseLong(args[0]); + int allocThreadNum = Integer.parseInt(args[1]); + int jniCriticalThreadNum = Integer.parseInt(args[2]); + + println("Running for " + durationSec + " secs"); + + if (!GCNotificationListener.register()) { + println("failed to register GC notification listener"); + System.exit(-1); + } + + largeMap = populateMap(LARGE_MAP_SIZE); + + println("Starting " + allocThreadNum + " allocating threads"); + for (int i = 0; i < allocThreadNum; i += 1) { + new Thread(new AllocatingWorker()).start(); + } + + println("Starting " + jniCriticalThreadNum + " jni critical threads"); + for (int i = 0; i < jniCriticalThreadNum; i += 1) { + new Thread(new JNICriticalWorker()).start(); + } + + long durationMS = (long) (1000 * durationSec); + long start = System.currentTimeMillis(); + long now = start; + long soFar = now - start; + while (soFar < durationMS) { + try { + Thread.sleep(durationMS - soFar); + } catch (Exception e) { + } + now = System.currentTimeMillis(); + soFar = now - start; + } + println("Done."); + keepRunning = false; + } +} + +public class TestExcessGCLockerCollections { + private static final String USED_OK_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_OK + "\\)"; + private static final String USED_TOO_LOW_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + "\\)"; + + private static final String[] COMMON_OPTIONS = new String[] { + "-Xmx1G", "-Xms1G", "-Xmn256M" }; + + public static void main(String args[]) throws Exception { + if (args.length < 3) { + System.out.println("usage: TestExcessGCLockerCollections" + + " " + + " "); + throw new RuntimeException("Invalid arguments"); + } + + ArrayList finalArgs = new ArrayList(); + finalArgs.addAll(Arrays.asList(COMMON_OPTIONS)); + finalArgs.add(TestExcessGCLockerCollectionsAux.class.getName()); + finalArgs.addAll(Arrays.asList(args)); + + // GC and other options obtained from test framework. + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + true, finalArgs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + //System.out.println("------------- begin stdout ----------------"); + //System.out.println(output.getStdout()); + //System.out.println("------------- end stdout ----------------"); + output.stdoutShouldMatch(USED_OK_LINE); + output.stdoutShouldNotMatch(USED_TOO_LOW_LINE); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/runtime/8003720/VictimClassLoader.java openjdk-8-8u242-b08/=unpacked-tar11=/test/runtime/8003720/VictimClassLoader.java --- openjdk-8-8u232-b09/=unpacked-tar11=/test/runtime/8003720/VictimClassLoader.java 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/runtime/8003720/VictimClassLoader.java 2020-01-13 05:52:26.000000000 +0000 @@ -22,6 +22,8 @@ * */ +import sun.misc.IOUtils; + public class VictimClassLoader extends ClassLoader { public static long counter = 0; @@ -72,8 +74,10 @@ } static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException { - // Warning here: - return sun.misc.IOUtils.readFully(in, len, true); + byte[] b = IOUtils.readAllBytes(in); + if (len != -1 && b.length != len) + throw new java.io.IOException("Expected:" + len + ", actual:" + b.length); + return b; } public void finalize() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/test/TEST.groups openjdk-8-8u242-b08/=unpacked-tar11=/test/TEST.groups --- openjdk-8-8u232-b09/=unpacked-tar11=/test/TEST.groups 2019-10-10 17:16:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/test/TEST.groups 2020-01-13 05:52:26.000000000 +0000 @@ -148,6 +148,7 @@ gc/logging/TestGCId.java \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/startup_warnings/TestShenandoah.java \ + gc/shenandoah/jvmti/TestGetLoadedClasses.sh \ gc/shenandoah/ -gc/shenandoah/TestStringDedupStress.java \ -gc/shenandoah/jni/TestCriticalNativeStress.sh \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar11=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar11=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar11=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar11=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar2=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar2=/.hg_archival.txt 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/.hg_archival.txt 2020-01-15 09:13:39.000000000 +0000 @@ -1,4 +1,4 @@ repo: a61af66fc99eb5ec9d50c05b0c599757b1289ceb -node: 03883da97d3b08819ea333f4f76e53b1ce8ab822 +node: 4107aea57664dbc44308e56f2067283ed8915c76 branch: default -tag: jdk8u232-b08-aarch32-191010 +tag: jdk8u242-b07-aarch32-200115 diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/.hgtags openjdk-8-8u242-b08/=unpacked-tar2=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar2=/.hgtags 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/.hgtags 2020-01-15 09:13:39.000000000 +0000 @@ -1309,7 +1309,25 @@ 921c5ee7965fdfde75f578ddda24d5cd16f124dc jdk8u232-b04 b13d7942036329f64c77a93cffc25e1b52523a3c jdk8u232-b05 52c26cd6c7e2c7812c1a80d737916554a877838d jdk8u232-b05-aarch32-190906 +760b28d871785cd508239a5f635cfb45451f9202 jdk8u242-b00 fea2c7f50ce8e6aee1e946eaec7b834193747d82 jdk8u232-b06 c751303497d539aa85c6373aa0fa85580d3f3044 jdk8u232-b07 6206dd7c35b8165f90aaccd3511a702e4265ee29 jdk8u232-b07-aarch32-190926 4170228e11e6313e948e6ddcae9af3eed06b1fbe jdk8u232-b08 +03883da97d3b08819ea333f4f76e53b1ce8ab822 jdk8u232-b08-aarch32-191010 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-b09 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-ga +fd0f7e6f5d8636bb654a35767bb700f880da1868 jdk8u232-b09-aarch32-191016 +0d7b61c79fee31075122f6ee338c31145653b094 jdk8u232-ga-aarch32-191016 +ce42ae95d4d671f74246091f89bd101d5bcbfd91 jdk8u242-b01 +1e62a32a85172eb1346148d84fc4f559c45f218a jdk8u242-b01-aarch32-191129 +775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02 +77f97ed9255819c72a9e674189d51cf270f5c598 jdk8u242-b02-aarch32-191202 +ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03 +20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04 +9036f4b16906554e56226568c25a150a9d63626c jdk8u242-b04-aarch32-191213 +2c1e9fab6964647f4eeffe55fe5592da6399a3ce jdk8u242-b05 +bef484473621573ad55e1fc78aaa4881913a839f jdk8u242-b05-aarch32-191230 +81ddc1072b923330f84c0ace3124226f63877582 jdk8u242-b06 +0454850187f669aaf6d76161bb9098b12fa03b53 jdk8u242-b06-aarch32-200109 +8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/ppc/vm/vm_version_ppc.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/ppc/vm/vm_version_ppc.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/ppc/vm/vm_version_ppc.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/ppc/vm/vm_version_ppc.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -194,6 +194,11 @@ FLAG_SET_DEFAULT(UseAESIntrinsics, false); } + if (UseGHASHIntrinsics) { + warning("GHASH intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + if (has_vshasig()) { if (FLAG_IS_DEFAULT(UseSHA)) { UseSHA = true; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/assembler_sparc.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/assembler_sparc.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/assembler_sparc.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/assembler_sparc.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -129,6 +129,7 @@ flog3_op3 = 0x36, edge_op3 = 0x36, fsrc_op3 = 0x36, + xmulx_op3 = 0x36, impdep2_op3 = 0x37, stpartialf_op3 = 0x37, jmpl_op3 = 0x38, @@ -220,6 +221,8 @@ mdtox_opf = 0x110, mstouw_opf = 0x111, mstosw_opf = 0x113, + xmulx_opf = 0x115, + xmulxhi_opf = 0x116, mxtod_opf = 0x118, mwtos_opf = 0x119, @@ -1212,6 +1215,9 @@ void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + void xmulx(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulx_opf) | rs2(s2)); } + void xmulxhi(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulxhi_opf) | rs2(s2)); } + // Crypto SHA instructions void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/stubGenerator_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -4788,6 +4788,130 @@ return start; } + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_aligned, L_main; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + Register state = I0; + Register subkeyH = I1; + Register data = I2; + Register len = I3; + + __ save_frame(0); + + __ ldx(state, 0, O0); + __ ldx(state, 8, O1); + + // Loop label for multiblock operations + __ BIND(L_ghash_loop); + + // Check if 'data' is unaligned + __ andcc(data, 7, G1); + __ br(Assembler::zero, false, Assembler::pt, L_aligned); + __ delayed()->nop(); + + Register left_shift = L1; + Register right_shift = L2; + Register data_ptr = L3; + + // Get left and right shift values in bits + __ sll(G1, LogBitsPerByte, left_shift); + __ mov(64, right_shift); + __ sub(right_shift, left_shift, right_shift); + + // Align to read 'data' + __ sub(data, G1, data_ptr); + + // Load first 8 bytes of 'data' + __ ldx(data_ptr, 0, O4); + __ sllx(O4, left_shift, O4); + __ ldx(data_ptr, 8, O5); + __ srlx(O5, right_shift, G4); + __ bset(G4, O4); + + // Load second 8 bytes of 'data' + __ sllx(O5, left_shift, O5); + __ ldx(data_ptr, 16, G4); + __ srlx(G4, right_shift, G4); + __ ba(L_main); + __ delayed()->bset(G4, O5); + + // If 'data' is aligned, load normally + __ BIND(L_aligned); + __ ldx(data, 0, O4); + __ ldx(data, 8, O5); + + __ BIND(L_main); + __ ldx(subkeyH, 0, O2); + __ ldx(subkeyH, 8, O3); + + __ xor3(O0, O4, O0); + __ xor3(O1, O5, O1); + + __ xmulxhi(O0, O3, G3); + __ xmulx(O0, O2, O5); + __ xmulxhi(O1, O2, G4); + __ xmulxhi(O1, O3, G5); + __ xmulx(O0, O3, G1); + __ xmulx(O1, O3, G2); + __ xmulx(O1, O2, O3); + __ xmulxhi(O0, O2, O4); + + __ mov(0xE1, O0); + __ sllx(O0, 56, O0); + + __ xor3(O5, G3, O5); + __ xor3(O5, G4, O5); + __ xor3(G5, G1, G1); + __ xor3(G1, O3, G1); + __ srlx(G2, 63, O1); + __ srlx(G1, 63, G3); + __ sllx(G2, 63, O3); + __ sllx(G2, 58, O2); + __ xor3(O3, O2, O2); + + __ sllx(G1, 1, G1); + __ or3(G1, O1, G1); + + __ xor3(G1, O2, G1); + + __ sllx(G2, 1, G2); + + __ xmulxhi(G1, O0, O1); + __ xmulx(G1, O0, O2); + __ xmulxhi(G2, O0, O3); + __ xmulx(G2, O0, G1); + + __ xor3(O4, O1, O4); + __ xor3(O5, O2, O5); + __ xor3(O5, O3, O5); + + __ sllx(O4, 1, O2); + __ srlx(O5, 63, O3); + + __ or3(O2, O3, O0); + + __ sllx(O5, 1, O1); + __ srlx(G1, 63, O2); + __ or3(O1, O2, O1); + __ xor3(O1, G3, O1); + + __ deccc(len); + __ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop); + __ delayed()->add(data, 16, data); + + __ stx(O0, I0, 0); + __ stx(O1, I0, 8); + + __ ret(); + __ delayed()->restore(); + + return start; + } + void generate_initial() { // Generates all stubs and initializes the entry points @@ -4860,6 +4984,10 @@ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } // generate SHA1/SHA256/SHA512 intrinsics code if (UseSHA1Intrinsics) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/vm_version_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/vm_version_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/sparc/vm/vm_version_sparc.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/sparc/vm/vm_version_sparc.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -286,39 +286,50 @@ // SPARC T4 and above should have support for AES instructions if (has_aes()) { - if (UseVIS > 2) { // AES intrinsics use MOVxTOd/MOVdTOx which are VIS3 - if (FLAG_IS_DEFAULT(UseAES)) { - FLAG_SET_DEFAULT(UseAES, true); - } - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - FLAG_SET_DEFAULT(UseAESIntrinsics, true); - } - // we disable both the AES flags if either of them is disabled on the command line - if (!UseAES || !UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAES, false); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + if (FLAG_IS_DEFAULT(UseAES)) { + FLAG_SET_DEFAULT(UseAES, true); + } + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); } else { - if (UseAES || UseAESIntrinsics) { - warning("SPARC AES intrinsics require VIS3 instruction support. Intrinsics will be disabled."); - if (UseAES) { - FLAG_SET_DEFAULT(UseAES, false); - } - if (UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAESIntrinsics, false); - } + // The AES intrinsic stubs require AES instruction support (of course) + // but also require VIS3 mode or higher for instructions it use. + if (UseVIS > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("SPARC AES intrinsics require VIS3 instructions. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } } else if (UseAES || UseAESIntrinsics) { - warning("AES instructions are not available on this CPU"); - if (UseAES) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { + warning("AES instructions are not available on this CPU"); FLAG_SET_DEFAULT(UseAES, false); } - if (UseAESIntrinsics) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); FLAG_SET_DEFAULT(UseAESIntrinsics, false); } } + // GHASH/GCM intrinsics + if (has_vis3() && (UseVIS > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; + } + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times if (has_sha1() || has_sha256() || has_sha512()) { if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -2575,6 +2575,15 @@ emit_int8(shift); } +void Assembler::pslldq(XMMRegister dst, int shift) { + // Shift left 128 bit value in xmm register by number of bytes. + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66); + emit_int8(0x73); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(shift); +} + void Assembler::ptest(XMMRegister dst, Address src) { assert(VM_Version::supports_sse4_1(), ""); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/assembler_x86.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -1527,6 +1527,8 @@ // Shift Right by bytes Logical DoubleQuadword Immediate void psrldq(XMMRegister dst, int shift); + // Shift Left by bytes Logical DoubleQuadword Immediate + void pslldq(XMMRegister dst, int shift); // Logical Compare 128bit void ptest(XMMRegister dst, XMMRegister src); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_32.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_32.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -2719,6 +2719,169 @@ return start; } + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data(0x0b0a0908, relocInfo::none, 0); + __ emit_data(0x0f0e0d0c, relocInfo::none, 0); + __ emit_data(0x03020100, relocInfo::none, 0); + __ emit_data(0x07060504, relocInfo::none, 0); + + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data(0x0c0d0e0f, relocInfo::none, 0); + __ emit_data(0x08090a0b, relocInfo::none, 0); + __ emit_data(0x04050607, relocInfo::none, 0); + __ emit_data(0x00010203, relocInfo::none, 0); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support"); + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = rdi; + const Register subkeyH = rsi; + const Register data = rdx; + const Register blocks = rcx; + + const Address state_param(rbp, 8+0); + const Address subkeyH_param(rbp, 8+4); + const Address data_param(rbp, 8+8); + const Address blocks_param(rbp, 8+12); + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + + __ enter(); + handleSOERegisters(true); // Save registers + + __ movptr(state, state_param); + __ movptr(subkeyH, subkeyH_param); + __ movptr(data, data_param); + __ movptr(blocks, blocks_param); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp6); + __ pslld (xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp4, 31); + __ movdqu(xmm_temp5, xmm_temp7); + __ pslldq(xmm_temp4, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp5, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp4); + __ por(xmm_temp6, xmm_temp5); + + // + // First phase of the reduction + // + // Move xmm3 into xmm4, xmm5, xmm7 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp4, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp5, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp5); + __ movdqu(xmm_temp4, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp4, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm5, xmm7 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp7, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp7); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp4); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + // Byte swap 16-byte result + __ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + __ movdqu(Address(state, 0), xmm_temp6); // store the result + + handleSOERegisters(false); // restore registers + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -3018,6 +3181,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -3639,6 +3639,175 @@ return start; } + + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data64(0x0f0e0d0c0b0a0908, relocInfo::none ); + __ emit_data64(0x0706050403020100, relocInfo::none ); + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none ); + __ emit_data64(0x0001020304050607, relocInfo::none ); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = c_rarg0; + const Register subkeyH = c_rarg1; + const Register data = c_rarg2; + const Register blocks = c_rarg3; + +#ifdef _WIN64 + const int XMM_REG_LAST = 10; +#endif + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + const XMMRegister xmm_temp8 = xmm8; + const XMMRegister xmm_temp9 = xmm9; + const XMMRegister xmm_temp10 = xmm10; + + __ enter(); + +#ifdef _WIN64 + // save the xmm registers which must be preserved 6-10 + __ subptr(rsp, -rsp_after_call_off * wordSize); + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(xmm_save(i), as_XMMRegister(i)); + } +#endif + + __ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, xmm_temp10); + + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, xmm_temp10); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp6); + __ pslld(xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp8, 31); + __ movdqu(xmm_temp9, xmm_temp7); + __ pslldq(xmm_temp8, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp9, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp8); + __ por(xmm_temp6, xmm_temp9); + + // + // First phase of the reduction + // + // Move xmm3 into xmm7, xmm8, xmm9 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp3); + __ movdqu(xmm_temp9, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp8, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp9, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp8); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp9); + __ movdqu(xmm_temp8, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp8, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm4, xmm5 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp4, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp8); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + __ pshufb(xmm_temp6, xmm_temp10); // Byte swap 16-byte result + __ movdqu(Address(state, 0), xmm_temp6); // store the result + +#ifdef _WIN64 + // restore xmm regs belonging to calling function + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(as_XMMRegister(i), xmm_save(i)); + } +#endif + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -4077,6 +4246,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -33,6 +33,8 @@ address StubRoutines::x86::_verify_mxcsr_entry = NULL; address StubRoutines::x86::_key_shuffle_mask_addr = NULL; +address StubRoutines::x86::_ghash_long_swap_mask_addr = NULL; +address StubRoutines::x86::_ghash_byte_swap_mask_addr = NULL; uint64_t StubRoutines::x86::_crc_by128_masks[] = { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/stubRoutines_x86.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,10 +36,15 @@ // masks and table for CRC32 static uint64_t _crc_by128_masks[]; static juint _crc_table[]; + // swap mask for ghash + static address _ghash_long_swap_mask_addr; + static address _ghash_byte_swap_mask_addr; public: static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } static address crc_by128_masks_addr() { return (address)_crc_by128_masks; } + static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; } + static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; } #endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/vm_version_x86.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/vm_version_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/cpu/x86/vm/vm_version_x86.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/cpu/x86/vm/vm_version_x86.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -553,12 +553,36 @@ // Use AES instructions if available. if (supports_aes()) { if (FLAG_IS_DEFAULT(UseAES)) { - UseAES = true; + FLAG_SET_DEFAULT(UseAES, true); } - } else if (UseAES) { - if (!FLAG_IS_DEFAULT(UseAES)) + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else { + if (UseSSE > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + // The AES intrinsic stubs require AES instruction support (of course) + // but also require sse3 mode or higher for instructions it use. + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("X86 AES intrinsics require SSE3 instructions or higher. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + } + } else if (UseAES || UseAESIntrinsics) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { warning("AES instructions are not available on this CPU"); - FLAG_SET_DEFAULT(UseAES, false); + FLAG_SET_DEFAULT(UseAES, false); + } + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } // Use CLMUL instructions if available. @@ -582,16 +606,15 @@ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); } - // The AES intrinsic stubs require AES instruction support (of course) - // but also require sse3 mode for instructions it use. - if (UseAES && (UseSSE > 2)) { - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - UseAESIntrinsics = true; + // GHASH/GCM intrinsics + if (UseCLMUL && (UseSSE > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; } - } else if (UseAESIntrinsics) { - if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) - warning("AES intrinsics are not available on this CPU"); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } if (UseSHA) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/c1/c1_LIR.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/c1/c1_LIR.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/c1/c1_LIR.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/c1/c1_LIR.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -2112,8 +2112,14 @@ // LIR_OpProfileType void LIR_OpProfileType::print_instr(outputStream* out) const { - out->print("exact = "); exact_klass()->print_name_on(out); - out->print("current = "); ciTypeEntries::print_ciklass(out, current_klass()); + out->print("exact = "); + if (exact_klass() == NULL) { + out->print("unknown"); + } else { + exact_klass()->print_name_on(out); + } + out->print(" current = "); ciTypeEntries::print_ciklass(out, current_klass()); + out->print(" "); mdp()->print(out); out->print(" "); obj()->print(out); out->print(" "); tmp()->print(out); out->print(" "); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/classfile/vmSymbols.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/classfile/vmSymbols.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/classfile/vmSymbols.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/classfile/vmSymbols.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -863,6 +863,12 @@ do_name( implCompressMB_name, "implCompressMultiBlock0") \ do_signature(implCompressMB_signature, "([BII)I") \ \ + /* support for com.sun.crypto.provider.GHASH */ \ + do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH") \ + do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \ + do_name(processBlocks_name, "processBlocks") \ + do_signature(ghash_processBlocks_signature, "([BII[J[J)V") \ + \ /* support for java.util.zip */ \ do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \ do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -161,6 +161,8 @@ } _dictionary->set_par_lock(&_parDictionaryAllocLock); } + + _used_stable = 0; } // Like CompactibleSpace forward() but always calls cross_threshold() to @@ -377,6 +379,14 @@ return capacity() - free(); } +size_t CompactibleFreeListSpace::used_stable() const { + return _used_stable; +} + +void CompactibleFreeListSpace::recalculate_used_stable() { + _used_stable = used(); +} + size_t CompactibleFreeListSpace::free() const { // "MT-safe, but not MT-precise"(TM), if you will: i.e. // if you do this while the structures are in flux you @@ -1218,6 +1228,13 @@ debug_only(fc->mangleAllocated(size)); } + // During GC we do not need to recalculate the stable used value for + // every allocation in old gen. It is done once at the end of GC instead + // for performance reasons. + if (!Universe::heap()->is_gc_active()) { + recalculate_used_stable(); + } + return res; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -148,6 +148,9 @@ // Used to keep track of limit of sweep for the space HeapWord* _sweep_limit; + // Stable value of used(). + size_t _used_stable; + // Support for compacting cms HeapWord* cross_threshold(HeapWord* start, HeapWord* end); HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); @@ -343,6 +346,17 @@ // which overestimates the region by returning the entire // committed region (this is safe, but inefficient). + // Returns monotonically increasing stable used space bytes for CMS. + // This is required for jstat and other memory monitoring tools + // that might otherwise see inconsistent used space values during a garbage + // collection, promotion or allocation into compactibleFreeListSpace. + // The value returned by this function might be smaller than the + // actual value. + size_t used_stable() const; + // Recalculate and cache the current stable used() value. Only to be called + // in places where we can be sure that the result is stable. + void recalculate_used_stable(); + // Returns a subregion of the space containing all the objects in // the space. MemRegion used_region() const { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -869,6 +869,10 @@ return _cmsSpace->max_alloc_in_words() * HeapWordSize; } +size_t ConcurrentMarkSweepGeneration::used_stable() const { + return cmsSpace()->used_stable(); +} + size_t ConcurrentMarkSweepGeneration::max_available() const { return free() + _virtual_space.uncommitted_size(); } @@ -1955,6 +1959,8 @@ FreelistLocker z(this); MetaspaceGC::compute_new_size(); _cmsGen->compute_new_size_free_list(); + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); } // A work method used by foreground collection to determine @@ -2768,6 +2774,7 @@ _capacity_at_prologue = capacity(); _used_at_prologue = used(); + _cmsSpace->recalculate_used_stable(); // Delegate to CMScollector which knows how to coordinate between // this and any other CMS generations that it is responsible for @@ -2837,6 +2844,7 @@ _eden_chunk_index = 0; size_t cms_used = _cmsGen->cmsSpace()->used(); + _cmsGen->cmsSpace()->recalculate_used_stable(); // update performance counters - this uses a special version of // update_counters() that allows the utilization to be passed as a @@ -3672,6 +3680,7 @@ _collectorState = Marking; } SpecializationStats::print(); + _cmsGen->cmsSpace()->recalculate_used_stable(); } void CMSCollector::checkpointRootsInitialWork(bool asynch) { @@ -5066,10 +5075,12 @@ Mutex::_no_safepoint_check_flag); assert(!init_mark_was_synchronous, "but that's impossible!"); checkpointRootsFinalWork(asynch, clear_all_soft_refs, false); + _cmsGen->cmsSpace()->recalculate_used_stable(); } else { // already have all the locks checkpointRootsFinalWork(asynch, clear_all_soft_refs, init_mark_was_synchronous); + _cmsGen->cmsSpace()->recalculate_used_stable(); } verify_work_stacks_empty(); verify_overflow_empty(); @@ -6368,6 +6379,10 @@ // Update heap occupancy information which is used as // input to soft ref clearing policy at the next gc. Universe::update_heap_info_at_gc(); + + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); + _collectorState = Resizing; } } else { @@ -6467,6 +6482,7 @@ // Gather statistics on the young generation collection. collector()->stats().record_gc0_end(used()); } + _cmsSpace->recalculate_used_stable(); } CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -1190,6 +1190,7 @@ double occupancy() const { return ((double)used())/((double)capacity()); } size_t contiguous_available() const; size_t unsafe_max_alloc_nogc() const; + size_t used_stable() const; // over-rides MemRegion used_region() const; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -2520,6 +2520,12 @@ } } } + } else if (GC_locker::should_discard(cause, gc_count_before)) { + // Return to be consistent with VMOp failure due to another + // collection slipping in after our gc_count but before our + // request is processed. _gc_locker collections upgraded by + // GCLockerInvokesConcurrent are handled above and never discarded. + return; } else { if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -376,7 +376,7 @@ MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes), 1U); _sizer_kind = SizerMaxAndNewSize; - _adaptive_size = _min_desired_young_length == _max_desired_young_length; + _adaptive_size = _min_desired_young_length != _max_desired_young_length; } else { _sizer_kind = SizerNewSizeOnly; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -133,7 +133,11 @@ SizerKind _sizer_kind; uint _min_desired_young_length; uint _max_desired_young_length; + + // False when using a fixed young generation size due to command-line options, + // true otherwise. bool _adaptive_size; + uint calculate_default_min_length(uint new_number_of_heap_regions); uint calculate_default_max_length(uint new_number_of_heap_regions); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -530,6 +530,10 @@ full_gc_count = Universe::heap()->total_full_collections(); } + if (GC_locker::should_discard(cause, gc_count)) { + return; + } + VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); VMThread::execute(&op); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -52,11 +52,16 @@ } } +static bool is_cause_full(GCCause::Cause cause) { + return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc) + DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot)); +} + // Only used for System.gc() calls VM_ParallelGCSystemGC::VM_ParallelGCSystemGC(uint gc_count, uint full_gc_count, GCCause::Cause gc_cause) : - VM_GC_Operation(gc_count, gc_cause, full_gc_count, true /* full */) + VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause)) { } @@ -68,8 +73,7 @@ "must be a ParallelScavengeHeap"); GCCauseSetter gccs(heap, _gc_cause); - if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc - DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) { + if (!_full) { // If (and only if) the scavenge fails, this will invoke a full gc. heap->invoke_scavenge(); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -63,7 +63,7 @@ } inline void update_used() { - _used->set_value(_gen->used()); + _used->set_value(_gen->used_stable()); } // special version of update_used() to allow the used value to be @@ -107,7 +107,7 @@ GenerationUsedHelper(Generation* g) : _gen(g) { } inline jlong take_sample() { - return _gen->used(); + return _gen->used_stable(); } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -201,6 +201,19 @@ } } +static bool is_full_gc(int max_level) { + // Return true if max_level is all generations + return (max_level == (GenCollectedHeap::heap()->n_gens() - 1)); +} + +VM_GenCollectFull::VM_GenCollectFull(uint gc_count_before, + uint full_gc_count_before, + GCCause::Cause gc_cause, + int max_level) : + VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, + is_full_gc(max_level) /* full */), + _max_level(max_level) { } + void VM_GenCollectFull::doit() { SvcGCMarker sgcm(SvcGCMarker::FULL); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -201,9 +201,7 @@ VM_GenCollectFull(uint gc_count_before, uint full_gc_count_before, GCCause::Cause gc_cause, - int max_level) - : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */), - _max_level(max_level) { } + int max_level); ~VM_GenCollectFull() {} virtual VMOp_Type type() const { return VMOp_GenCollectFull; } virtual void doit(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/gcLocker.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/gcLocker.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/gcLocker.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/gcLocker.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -31,6 +31,7 @@ volatile jint GC_locker::_jni_lock_count = 0; volatile bool GC_locker::_needs_gc = false; volatile bool GC_locker::_doing_gc = false; +unsigned int GC_locker::_total_collections = 0; #ifdef ASSERT volatile jint GC_locker::_debug_jni_lock_count = 0; @@ -94,6 +95,11 @@ } } +bool GC_locker::should_discard(GCCause::Cause cause, uint total_collections) { + return (cause == GCCause::_gc_locker) && + (_total_collections != total_collections); +} + void GC_locker::jni_lock(JavaThread* thread) { assert(!thread->in_critical(), "shouldn't currently be in a critical region"); MutexLocker mu(JNICritical_lock); @@ -117,7 +123,13 @@ decrement_debug_jni_lock_count(); thread->exit_critical(); if (needs_gc() && !is_active_internal()) { - // We're the last thread out. Cause a GC to occur. + // We're the last thread out. Request a GC. + // Capture the current total collections, to allow detection of + // other collections that make this one unnecessary. The value of + // total_collections() is only changed at a safepoint, so there + // must not be a safepoint between the lock becoming inactive and + // getting the count, else there may be unnecessary GCLocker GCs. + _total_collections = Universe::heap()->total_collections(); _doing_gc = true; { // Must give up the lock while at a safepoint diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/gcLocker.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/gcLocker.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/gcLocker.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/gcLocker.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -26,6 +26,7 @@ #define SHARE_VM_MEMORY_GCLOCKER_HPP #include "gc_interface/collectedHeap.hpp" +#include "gc_interface/gcCause.hpp" #include "memory/genCollectedHeap.hpp" #include "memory/universe.hpp" #include "oops/oop.hpp" @@ -57,6 +58,7 @@ static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC + static uint _total_collections; // value for _gc_locker collection #ifdef ASSERT // This lock count is updated for all operations and is used to @@ -116,6 +118,12 @@ // Sets _needs_gc if is_active() is true. Returns is_active(). static bool check_active_before_gc(); + // Return true if the designated collection is a GCLocker request + // that should be discarded. Returns true if cause == GCCause::_gc_locker + // and the given total collection value indicates a collection has been + // done since the GCLocker request was made. + static bool should_discard(GCCause::Cause cause, uint total_collections); + // Stalls the caller (who should not be in a jni critical section) // until needs_gc() clears. Note however that needs_gc() may be // set at a subsequent safepoint and/or cleared under the diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/genCollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/genCollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/genCollectedHeap.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/genCollectedHeap.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -796,8 +796,11 @@ #else // INCLUDE_ALL_GCS ShouldNotReachHere(); #endif // INCLUDE_ALL_GCS - } else if (cause == GCCause::_wb_young_gc) { - // minor collection for WhiteBox API + } else if ((cause == GCCause::_wb_young_gc) || + (cause == GCCause::_gc_locker)) { + // minor collection for WhiteBox or GCLocker. + // _gc_locker collections upgraded by GCLockerInvokesConcurrent + // are handled above and never discarded. collect(cause, 0); } else { #ifdef ASSERT @@ -835,6 +838,11 @@ // Read the GC count while holding the Heap_lock unsigned int gc_count_before = total_collections(); unsigned int full_gc_count_before = total_full_collections(); + + if (GC_locker::should_discard(cause, gc_count_before)) { + return; + } + { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back VM_GenCollectFull op(gc_count_before, full_gc_count_before, @@ -887,24 +895,16 @@ void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, int max_level) { - int local_max_level; - if (!incremental_collection_will_fail(false /* don't consult_young */) && - gc_cause() == GCCause::_gc_locker) { - local_max_level = 0; - } else { - local_max_level = max_level; - } do_collection(true /* full */, clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - local_max_level /* max_level */); + max_level /* max_level */); // Hack XXX FIX ME !!! // A scavenge may not have been attempted, or may have // been attempted and failed, because the old gen was too full - if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker && - incremental_collection_will_fail(false /* don't consult_young */)) { + if (gc_cause() == GCCause::_gc_locker && incremental_collection_failed()) { if (PrintGCDetails) { gclog_or_tty->print_cr("GC locker: Trying a full collection " "because scavenge failed"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/generation.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/generation.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/generation.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/generation.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -68,6 +68,12 @@ return gch->_gen_specs[level()]; } +// This is for CMS. It returns stable monotonic used space size. +// Remove this when CMS is removed. +size_t Generation::used_stable() const { + return used(); +} + size_t Generation::max_capacity() const { return reserved().byte_size(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/generation.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/generation.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/memory/generation.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/memory/generation.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -168,6 +168,7 @@ virtual size_t capacity() const = 0; // The maximum number of object bytes the // generation can currently hold. virtual size_t used() const = 0; // The number of used bytes in the gen. + virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools. virtual size_t free() const = 0; // The number of free bytes in the gen. // Support for java.lang.Runtime.maxMemory(); see CollectedHeap. diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/instanceKlass.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/instanceKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/instanceKlass.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/instanceKlass.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -294,6 +294,7 @@ set_has_unloaded_dependent(false); set_init_state(InstanceKlass::allocated); set_init_thread(NULL); + set_init_state(allocated); set_reference_type(rt); set_oop_map_cache(NULL); set_jni_ids(NULL); @@ -978,11 +979,13 @@ oop init_lock = this_oop->init_lock(); if (init_lock != NULL) { ObjectLocker ol(init_lock, THREAD); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); this_oop->fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(init_lock != NULL, "The initialization state should never be set twice"); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); } } @@ -3602,6 +3605,7 @@ bool good_state = is_shared() ? (_init_state <= state) : (_init_state < state); assert(good_state || state == allocated, "illegal state transition"); + assert(_init_thread == NULL, "should be cleared before state change"); _init_state = (u1)state; } #endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/instanceKlass.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/instanceKlass.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/instanceKlass.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/instanceKlass.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -241,7 +241,7 @@ u2 _misc_flags; u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file - Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) + Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/klassVtable.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/klassVtable.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/oops/klassVtable.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/oops/klassVtable.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -289,22 +289,25 @@ int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { InstanceKlass* superk = initialsuper; while (superk != NULL && superk->super() != NULL) { - InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); - klassVtable* ssVtable = supersuperklass->vtable(); + klassVtable* ssVtable = (superk->super())->vtable(); if (vtable_index < ssVtable->length()) { Method* super_method = ssVtable->method_at(vtable_index); + // get the class holding the matching method + // make sure you use that class for is_override + InstanceKlass* supermethodholder = super_method->method_holder(); #ifndef PRODUCT Symbol* name= target_method()->name(); Symbol* signature = target_method()->signature(); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif - if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { + + if (supermethodholder->is_override(super_method, target_loader, target_classname, THREAD)) { #ifndef PRODUCT if (PrintVtables && Verbose) { ResourceMark rm(THREAD); char* sig = target_method()->name_and_sig_as_C_string(); tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", - supersuperklass->internal_name(), + supermethodholder->internal_name(), _klass->internal_name(), sig, vtable_index); super_method->access_flags().print_on(tty); if (super_method->is_default_method()) { @@ -656,7 +659,7 @@ // search through the super class hierarchy to see if we need // a new entry - ResourceMark rm; + ResourceMark rm(THREAD); Symbol* name = target_method()->name(); Symbol* signature = target_method()->signature(); Klass* k = super; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/escape.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/escape.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/escape.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/escape.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -952,6 +952,7 @@ strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || + strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 || @@ -2114,6 +2115,9 @@ return false; } PointsToNode* ptn = ptnode_adr(idx); + if (ptn == NULL) { + return false; // not in congraph (e.g. ConI) + } PointsToNode::EscapeState es = ptn->escape_state(); // If we have already computed a value, return it. if (es >= PointsToNode::GlobalEscape) diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/library_call.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/library_call.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/library_call.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/library_call.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -311,6 +311,7 @@ Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); + bool inline_ghash_processBlocks(); bool inline_sha_implCompress(vmIntrinsics::ID id); bool inline_digestBase_implCompressMB(int predicate); bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, @@ -570,6 +571,10 @@ predicates = 3; break; + case vmIntrinsics::_ghash_processBlocks: + if (!UseGHASHIntrinsics) return NULL; + break; + case vmIntrinsics::_updateCRC32: case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: @@ -957,6 +962,9 @@ case vmIntrinsics::_montgomerySquare: return inline_montgomerySquare(); + case vmIntrinsics::_ghash_processBlocks: + return inline_ghash_processBlocks(); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -6599,6 +6607,35 @@ return _gvn.transform(region); } +//------------------------------inline_ghash_processBlocks +bool LibraryCallKit::inline_ghash_processBlocks() { + address stubAddr; + const char *stubName; + assert(UseGHASHIntrinsics, "need GHASH intrinsics support"); + + stubAddr = StubRoutines::ghash_processBlocks(); + stubName = "ghash_processBlocks"; + + Node* data = argument(0); + Node* offset = argument(1); + Node* len = argument(2); + Node* state = argument(3); + Node* subkeyH = argument(4); + + Node* state_start = array_element_address(state, intcon(0), T_LONG); + assert(state_start, "state is NULL"); + Node* subkeyH_start = array_element_address(subkeyH, intcon(0), T_LONG); + assert(subkeyH_start, "subkeyH is NULL"); + Node* data_start = array_element_address(data, offset, T_BYTE); + assert(data_start, "data is NULL"); + + Node* ghash = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::ghash_processBlocks_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + state_start, subkeyH_start, data_start, len); + return true; +} + //------------------------------inline_sha_implCompress----------------------- // // Calculate SHA (i.e., SHA-1) for single-block byte[] array. diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopnode.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopnode.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopnode.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopnode.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -279,6 +279,7 @@ if (iv_phi == NULL) { return NULL; } + assert(iv_phi->is_Phi(), "should be PhiNode"); Node *ln = iv_phi->in(0); if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) { return (CountedLoopNode*)ln; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopopts.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopopts.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopopts.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopopts.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -309,7 +309,7 @@ } return NULL; } - assert(m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); + assert(n->is_Phi() || m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); } return n_ctrl; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopTransform.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopTransform.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/loopTransform.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/loopTransform.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2231,6 +2231,13 @@ // We also need to replace the original limit to collapse loop exit. Node* cmp = cl->loopexit()->cmp_node(); assert(cl->limit() == cmp->in(2), "sanity"); + // Duplicate cmp node if it has other users + if (cmp->outcnt() > 1) { + cmp = cmp->clone(); + cmp = phase->_igvn.register_new_node_with_optimizer(cmp); + BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool(); + phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist + } phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/runtime.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/runtime.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/runtime.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/runtime.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -94,7 +94,25 @@ // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000 +// GHASH block processing +const TypeFunc* OptoRuntime::ghash_processBlocks_Type() { + int argcnt = 4; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypePtr::NOTNULL; // subkeyH + fields[argp++] = TypePtr::NOTNULL; // data + fields[argp++] = TypeInt::INT; // blocks + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = NULL; // void + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); +} // Compiled code entry points address OptoRuntime::_new_instance_Java = NULL; diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/runtime.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/runtime.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/runtime.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/runtime.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -311,6 +311,8 @@ static const TypeFunc* montgomeryMultiply_Type(); static const TypeFunc* montgomerySquare_Type(); + static const TypeFunc* ghash_processBlocks_Type(); + static const TypeFunc* updateBytesCRC32_Type(); // leaf on stack replacement interpreter accessor types diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/superword.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/superword.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/opto/superword.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/opto/superword.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -448,6 +448,7 @@ return true; // no induction variable } CountedLoopEndNode* pre_end = get_pre_loop_end(lp()->as_CountedLoop()); + assert(pre_end != NULL, "we must have a correct pre-loop"); assert(pre_end->stride_is_con(), "pre loop stride is constant"); int preloop_stride = pre_end->stride_con(); @@ -2052,7 +2053,7 @@ CountedLoopNode *main_head = lp()->as_CountedLoop(); assert(main_head->is_main_loop(), ""); CountedLoopEndNode* pre_end = get_pre_loop_end(main_head); - assert(pre_end != NULL, ""); + assert(pre_end != NULL, "we must have a correct pre-loop"); Node *pre_opaq1 = pre_end->limit(); assert(pre_opaq1->Opcode() == Op_Opaque1, ""); Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1; @@ -2207,16 +2208,27 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. -CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) { - Node *ctrl = cl->in(LoopNode::EntryControl); +CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { + Node* ctrl = cl->in(LoopNode::EntryControl); if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node *iffm = ctrl->in(0); + Node* iffm = ctrl->in(0); if (!iffm->is_If()) return NULL; - Node *p_f = iffm->in(0); + Node* bolzm = iffm->in(1); + if (!bolzm->is_Bool()) return NULL; + Node* cmpzm = bolzm->in(1); + if (!cmpzm->is_Cmp()) return NULL; + Node* opqzm = cmpzm->in(2); + // Can not optimize a loop if zero-trip Opaque1 node is optimized + // away and then another round of loop opts attempted. + if (opqzm->Opcode() != Op_Opaque1) { + return NULL; + } + Node* p_f = iffm->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; - CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); - if (!pre_end->loopnode()->is_pre_loop()) return NULL; + CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); + CountedLoopNode* loop_node = pre_end->loopnode(); + if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL; return pre_end; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/globals.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/globals.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/globals.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/globals.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -615,6 +615,9 @@ product(bool, UseSHA, false, \ "Control whether SHA instructions can be used on SPARC") \ \ + product(bool, UseGHASHIntrinsics, false, \ + "Use intrinsics for GHASH versions of crypto") \ + \ product(uintx, LargePageSizeInBytes, 0, \ "Large page size (0 to let VM choose the page size)") \ \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/safepoint.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/safepoint.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/safepoint.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/safepoint.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -541,6 +541,7 @@ // rotate log files? if (UseGCLogFileRotation) { + TraceTime t8("rotating gc logs", TraceSafepointCleanupTime); gclog_or_tty->rotate_log(false); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -124,6 +124,7 @@ address StubRoutines::_aescrypt_decryptBlock = NULL; address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL; address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL; +address StubRoutines::_ghash_processBlocks = NULL; address StubRoutines::_sha1_implCompress = NULL; address StubRoutines::_sha1_implCompressMB = NULL; @@ -176,7 +177,7 @@ StubGenerator_generate(&buffer, false); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size1"); + assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1"); } } @@ -231,7 +232,7 @@ StubGenerator_generate(&buffer, true); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size2"); + assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2"); } #ifdef ASSERT diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/stubRoutines.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -203,6 +203,7 @@ static address _aescrypt_decryptBlock; static address _cipherBlockChaining_encryptAESCrypt; static address _cipherBlockChaining_decryptAESCrypt; + static address _ghash_processBlocks; static address _sha1_implCompress; static address _sha1_implCompressMB; @@ -365,6 +366,7 @@ static address aescrypt_decryptBlock() { return _aescrypt_decryptBlock; } static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; } static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; } + static address ghash_processBlocks() { return _ghash_processBlocks; } static address sha1_implCompress() { return _sha1_implCompress; } static address sha1_implCompressMB() { return _sha1_implCompressMB; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/vmStructs.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/vmStructs.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/runtime/vmStructs.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/runtime/vmStructs.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -818,6 +818,7 @@ static_field(StubRoutines, _aescrypt_decryptBlock, address) \ static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _ghash_processBlocks, address) \ static_field(StubRoutines, _updateBytesCRC32, address) \ static_field(StubRoutines, _crc_table_adr, address) \ static_field(StubRoutines, _multiplyToLen, address) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/allocationSite.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/allocationSite.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/allocationSite.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/allocationSite.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -34,8 +34,9 @@ private: NativeCallStack _call_stack; E e; + MEMFLAGS _flag; public: - AllocationSite(const NativeCallStack& stack) : _call_stack(stack) { } + AllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : _call_stack(stack), _flag(flag) { } int hash() const { return _call_stack.hash(); } bool equals(const NativeCallStack& stack) const { return _call_stack.equals(stack); @@ -52,6 +53,8 @@ // Information regarding this allocation E* data() { return &e; } const E* peek() const { return &e; } + + MEMFLAGS flag() const { return _flag; } }; #endif // SHARE_VM_SERVICES_ALLOCATION_SITE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,12 +84,18 @@ // Create pseudo call stack for hashtable entry allocation address pc[3]; if (NMT_TrackingStackDepth >= 3) { - pc[2] = (address)MallocSiteTable::allocation_at; + uintx *fp = (uintx*)MallocSiteTable::allocation_at; + // On ppc64, 'fp' is a pointer to a function descriptor which is a struct of + // three native pointers where the first pointer is the real function address. + // See: http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES + pc[2] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } if (NMT_TrackingStackDepth >= 2) { - pc[1] = (address)MallocSiteTable::lookup_or_add; + uintx *fp = (uintx*)MallocSiteTable::lookup_or_add; + pc[1] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } - pc[0] = (address)MallocSiteTable::new_entry; + uintx *fp = (uintx*)MallocSiteTable::new_entry; + pc[0] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); // Instantiate NativeCallStack object, have to use placement new operator. (see comments above) NativeCallStack* stack = ::new ((void*)_hash_entry_allocation_stack) @@ -158,7 +164,7 @@ MallocSiteHashtableEntry* head = _table[index]; while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { MallocSite* site = head->data(); - if (site->flags() == flags && site->equals(key)) { + if (site->flag() == flags && site->equals(key)) { return head->data(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/mallocSiteTable.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -37,15 +37,12 @@ // MallocSite represents a code path that eventually calls // os::malloc() to allocate memory class MallocSite : public AllocationSite { - private: - MEMFLAGS _flags; - public: MallocSite() : - AllocationSite(NativeCallStack::empty_stack()), _flags(mtNone) {} + AllocationSite(NativeCallStack::empty_stack(), mtNone) {} MallocSite(const NativeCallStack& stack, MEMFLAGS flags) : - AllocationSite(stack), _flags(flags) {} + AllocationSite(stack, flags) {} void allocate(size_t size) { data()->allocate(size); } @@ -55,7 +52,6 @@ size_t size() const { return peek()->size(); } // The number of calls were made size_t count() const { return peek()->count(); } - MEMFLAGS flags() const { return (MEMFLAGS)_flags; } }; // Malloc site hashtable entry diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memBaseline.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memBaseline.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memBaseline.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memBaseline.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) { int res = compare_malloc_site(s1, s2); if (res == 0) { - res = (int)(s1.flags() - s2.flags()); + res = (int)(s1.flag() - s2.flag()); } return res; @@ -209,7 +209,7 @@ const ReservedMemoryRegion* rgn; VirtualMemoryAllocationSite* site; while ((rgn = itr.next()) != NULL) { - VirtualMemoryAllocationSite tmp(*rgn->call_stack()); + VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag()); site = allocation_sites.find(tmp); if (site == NULL) { LinkedListNode* node = diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memoryPool.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memoryPool.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memoryPool.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memoryPool.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -198,7 +198,7 @@ bool support_usage_threshold); MemoryUsage get_memory_usage(); - size_t used_in_bytes() { return _space->used(); } + size_t used_in_bytes() { return _space->used_stable(); } }; #endif // INCLUDE_ALL_GCS diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memReporter.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memReporter.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memReporter.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memReporter.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -205,7 +205,7 @@ const NativeCallStack* stack = malloc_site->call_stack(); stack->print_on(out); out->print("%29s", " "); - MEMFLAGS flag = malloc_site->flags(); + MEMFLAGS flag = malloc_site->flag(); assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone, "Must have a valid memory type"); print_malloc(malloc_site->size(), malloc_site->count(),flag); @@ -231,6 +231,10 @@ stack->print_on(out); out->print("%28s (", " "); print_total(virtual_memory_site->reserved(), virtual_memory_site->committed()); + MEMFLAGS flag = virtual_memory_site->flag(); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } out->print_cr(")\n"); } } @@ -562,24 +566,24 @@ void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(), - 0, 0, malloc_site->flags()); + 0, 0, malloc_site->flag()); } void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(), - malloc_site->count(), malloc_site->flags()); + malloc_site->count(), malloc_site->flag()); } void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early, const MallocSite* current) const { - if (early->flags() != current->flags()) { + if (early->flag() != current->flag()) { // If malloc site type changed, treat it as deallocation of old type and // allocation of new type. old_malloc_site(early); new_malloc_site(current); } else { diff_malloc_site(current->call_stack(), current->size(), current->count(), - early->size(), early->count(), early->flags()); + early->size(), early->count(), early->flag()); } } @@ -603,21 +607,22 @@ void MemDetailDiffReporter::new_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0); + diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0, site->flag()); } void MemDetailDiffReporter::old_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed()); + diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed(), site->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, const VirtualMemoryAllocationSite* current) const { + assert(early->flag() == current->flag(), "Should be the same"); diff_virtual_memory_site(current->call_stack(), current->reserved(), current->committed(), - early->reserved(), early->committed()); + early->reserved(), early->committed(), current->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const { + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const { outputStream* out = output(); // no change @@ -631,6 +636,10 @@ print_virtual_memory_diff(current_reserved, current_committed, early_reserved, early_committed); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } + out->print_cr(")\n"); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memReporter.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memReporter.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/memReporter.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/memReporter.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -218,7 +218,7 @@ void diff_malloc_site(const NativeCallStack* stack, size_t current_size, size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const; void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const; + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; }; #endif // INCLUDE_NMT diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/virtualMemoryTracker.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/virtualMemoryTracker.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/services/virtualMemoryTracker.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/services/virtualMemoryTracker.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -69,8 +69,8 @@ // Virtual memory allocation site, keeps track where the virtual memory is reserved. class VirtualMemoryAllocationSite : public AllocationSite { public: - VirtualMemoryAllocationSite(const NativeCallStack& stack) : - AllocationSite(stack) { } + VirtualMemoryAllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : + AllocationSite(stack, flag) { } inline void reserve_memory(size_t sz) { data()->reserve_memory(sz); } inline void commit_memory (size_t sz) { data()->commit_memory(sz); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/macros.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/macros.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/macros.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/macros.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -424,6 +424,14 @@ #define NOT_EMBEDDED(code) code #endif +#ifdef VM_LITTLE_ENDIAN +#define LITTLE_ENDIAN_ONLY(code) code +#define BIG_ENDIAN_ONLY(code) +#else +#define LITTLE_ENDIAN_ONLY(code) +#define BIG_ENDIAN_ONLY(code) code +#endif + #define define_pd_global(type, name, value) const type pd_##name = value; #endif // SHARE_VM_UTILITIES_MACROS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/taskqueue.hpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/taskqueue.hpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/taskqueue.hpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/taskqueue.hpp 2020-01-15 09:13:39.000000000 +0000 @@ -714,6 +714,11 @@ } else { // Otherwise, the queue contained exactly one element; we take the slow // path. + + // The barrier is required to prevent reordering the two reads of _age: + // one is the _age.get() below, and the other is _age.top() above the if-stmt. + // The algorithm may fail if _age.get() reads an older value than _age.top(). + OrderAccess::loadload(); return pop_local_slow(localBot, _age.get()); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/workgroup.cpp openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/workgroup.cpp --- openjdk-8-8u232-b09/=unpacked-tar2=/src/share/vm/utilities/workgroup.cpp 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/src/share/vm/utilities/workgroup.cpp 2020-01-15 09:13:39.000000000 +0000 @@ -464,7 +464,6 @@ if (old == 0) { old = Atomic::cmpxchg(1, &_tasks[t], 0); } - assert(_tasks[t] == 1, "What else?"); bool res = old != 0; #ifdef ASSERT if (!res) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESBase.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESBase.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESBase.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESBase.java 2020-01-15 09:13:39.000000000 +0000 @@ -29,6 +29,7 @@ import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.AlgorithmParameters; @@ -62,8 +63,12 @@ Random random = new Random(0); Cipher cipher; Cipher dCipher; - AlgorithmParameters algParams; + AlgorithmParameters algParams = null; SecretKey key; + GCMParameterSpec gcm_spec; + byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 }; + int tlen = 12; + byte[] iv = new byte[16]; static int numThreads = 0; int threadId; @@ -77,7 +82,10 @@ public void prepare() { try { - System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); + System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 ) testingMisalignment = true; @@ -98,16 +106,24 @@ cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + // CBC init if (mode.equals("CBC")) { - int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0); - IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]); + IvParameterSpec initVector = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, key, initVector); - } else { algParams = cipher.getParameters(); + dCipher.init(Cipher.DECRYPT_MODE, key, initVector); + + // GCM init + } else if (mode.equals("GCM")) { + gcm_init(true); + gcm_init(false); + + // ECB init + } else { cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); } - algParams = cipher.getParameters(); - dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (threadId == 0) { childShowCipher(); } @@ -188,4 +204,19 @@ } abstract void childShowCipher(); + + void gcm_init(boolean encrypt) throws Exception { + gcm_spec = new GCMParameterSpec(tlen * 8, iv); + if (encrypt) { + // Get a new instance everytime because of reuse IV restrictions + cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec); + cipher.updateAAD(aad); + } else { + dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec); + dCipher.updateAAD(aad); + + + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESDecode.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESDecode.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESDecode.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESDecode.java 2020-01-15 09:13:39.000000000 +0000 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(false); + } else if (!noReinit) { + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + } decode = new byte[decodeLength]; if (testingMisalignment) { int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESEncode.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESEncode.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESEncode.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESEncode.java 2020-01-15 09:13:39.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(true); + } else if (!noReinit) { + cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + } encode = new byte[encodeLength]; if (testingMisalignment) { int tempSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESMain.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESMain.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/7184394/TestAESMain.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/7184394/TestAESMain.java 2020-01-15 09:13:39.000000000 +0000 @@ -41,6 +41,13 @@ * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain * * @author Tom Deneau */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2020-01-15 09:13:39.000000000 +0000 @@ -22,9 +22,10 @@ */ import sun.hotspot.WhiteBox; -import sun.misc.Unsafe; import sun.misc.IOUtils; +import sun.misc.Unsafe; +import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; @@ -108,7 +109,13 @@ // (1) Load an anonymous version of this class using the corresponding Unsafe method URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class"); URLConnection connection = classUrl.openConnection(); - byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true); + + int length = connection.getContentLength(); + byte[] classBytes = IOUtils.readAllBytes(connection.getInputStream()); + if (length != -1 && classBytes.length != length) { + throw new IOException("Expected:" + length + ", actual: " + classBytes.length); + } + Class anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null); // (2) Make sure all paths of doWork are profiled and compiled diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/StrangeControl.jasm openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/StrangeControl.jasm --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/StrangeControl.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/StrangeControl.jasm 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class compiler/loopopts/StrangeControl + version 51:0 +{ + +static Field field:"I"; + +public static Method test:"(I)V" + stack 2 locals 2 +{ + iconst_0; + istore 1; + L1: stack_frame_type append; + locals_map int; + iinc 1, 1; + iload 1; + iconst_2; + if_icmple L1; + L2: stack_frame_type same; + iload_0; + putstatic Field field:"I"; + goto L1; +} + +} // end Class StrangeControl diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/superword/TestFuzzPreLoop.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/superword/TestFuzzPreLoop.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8134739 8010500 + * @summary SEGV in SuperWord::get_pre_loop_end + * @run main/othervm compiler.loopopts.superword.TestFuzzPreLoop + */ + +package compiler.loopopts.superword; + +public class TestFuzzPreLoop { + static Object sink; + short sFld = -19206; + + void doTest() { + int[] arr = new int[400]; + + for (int i1 = 0; i1 < 200; i1++) { + for (int i2 = 0; i2 < 100; i2++) { + sink = new int[400]; + } + arr[i1] = 0; + } + + float f1 = 0; + for (int i3 = 0; i3 < 200; i3++) { + f1 += i3 * i3; + } + for (int i4 = 0; i4 < 200; i4++) { + f1 += i4 - sFld; + } + + System.out.println(arr); + System.out.println(f1); + } + + public static void main(String... args) throws Exception { + TestFuzzPreLoop test = new TestFuzzPreLoop(); + for (int i = 0; i < 100; i++) { + test.doTest(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/TestRemoveEmptyLoop.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/TestRemoveEmptyLoop.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/TestRemoveEmptyLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/TestRemoveEmptyLoop.java 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8231988 + * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation + * TestRemoveEmptyLoop + */ + +public class TestRemoveEmptyLoop { + + public void test() { + int i = 34; + for (; i > 0; i -= 11); + if (i < 0) { + // do nothing + } else { + throw new RuntimeException("Test failed."); + } + } + + public static void main(String[] args) { + TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop(); + for (int i = 0; i < 50000; i++) { + _instance.test(); + } + System.out.println("Test passed."); + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/TestStrangeControl.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/TestStrangeControl.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/loopopts/TestStrangeControl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/loopopts/TestStrangeControl.java 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8228888 + * @summary Test PhaseIdealLoop::has_local_phi_input() with phi input with non-dominating control. + * @compile StrangeControl.jasm + * @run main/othervm -Xbatch -XX:CompileCommand=inline,compiler.loopopts.StrangeControl::test + * compiler.loopopts.TestStrangeControl + */ + +package compiler.loopopts; + +public class TestStrangeControl { + + public static void main(String[] args) throws Exception { + Thread thread = new Thread() { + public void run() { + // Run this in an own thread because it's basically an endless loop + StrangeControl.test(42); + } + }; + thread.start(); + // Give thread executing strange control loop enough time to trigger OSR compilation + Thread.sleep(4000); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/print/TestProfileReturnTypePrinting.java openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/print/TestProfileReturnTypePrinting.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/compiler/print/TestProfileReturnTypePrinting.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/compiler/print/TestProfileReturnTypePrinting.java 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8073154 + * @build TestProfileReturnTypePrinting + * @run main/othervm -XX:TypeProfileLevel=020 + * -XX:CompileOnly=TestProfileReturnTypePrinting.testMethod + * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintLIR + * TestProfileReturnTypePrinting + * @summary Verify that c1's LIR that contains ProfileType node could be dumped + * without a crash disregard to an exact class knowledge. + */ +public class TestProfileReturnTypePrinting { + private static final int ITERATIONS = 1_000_000; + + public static void main(String args[]) { + for (int i = 0; i < ITERATIONS; i++) { + TestProfileReturnTypePrinting.testMethod(i); + } + } + + private static int testMethod(int i) { + return TestProfileReturnTypePrinting.foo().hashCode() + + TestProfileReturnTypePrinting.bar(i).hashCode(); + } + + /* Exact class of returned value is known statically. */ + private static B foo() { + return new B(); + } + + /* Exact class of returned value is not known statically. */ + private static Object bar(int i) { + if (i % 2 == 0) { + return new A(); + } else { + return new B(); + } + } + + private static class A { + } + + private static class B extends A { + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java openjdk-8-8u242-b08/=unpacked-tar2=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 2020-01-15 09:13:39.000000000 +0000 @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package gc.stress.gclocker; + +// Based on Kim Barrett;s test for JDK-8048556 + +/* + * @test TestExcessGCLockerCollections + * @key gc + * @bug 8048556 + * @summary Check for GC Locker initiated GCs that immediately follow another + * GC and so have very little needing to be collected. + * @library /testlibrary + * @run driver/timeout=1000 gc.stress.gclocker.TestExcessGCLockerCollections 300 4 2 + */ + +import java.util.HashMap; +import java.util.Map; + +import java.util.zip.Deflater; + +import java.util.ArrayList; +import java.util.Arrays; + +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; +import java.lang.management.ManagementFactory; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import com.sun.management.GarbageCollectionNotificationInfo; +import com.sun.management.GcInfo; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +class TestExcessGCLockerCollectionsStringConstants { + // Some constant strings used in both GC logging and error detection + static public final String GCLOCKER_CAUSE = "GCLocker Initiated GC"; + static public final String USED_TOO_LOW = "TOO LOW"; + static public final String USED_OK = "OK"; +} + +class TestExcessGCLockerCollectionsAux { + static private final int LARGE_MAP_SIZE = 64 * 1024; + + static private final int MAP_ARRAY_LENGTH = 4; + static private final int MAP_SIZE = 1024; + + static private final int BYTE_ARRAY_LENGTH = 128 * 1024; + + static private void println(String str) { System.out.println(str); } + static private void println() { System.out.println(); } + + static private volatile boolean keepRunning = true; + + static Map populateMap(int size) { + Map map = new HashMap(); + for (int i = 0; i < size; i += 1) { + Integer keyInt = Integer.valueOf(i); + String valStr = "value is [" + i + "]"; + map.put(keyInt,valStr); + } + return map; + } + + static private class AllocatingWorker implements Runnable { + private final Object[] array = new Object[MAP_ARRAY_LENGTH]; + private int arrayIndex = 0; + + private void doStep() { + Map map = populateMap(MAP_SIZE); + array[arrayIndex] = map; + arrayIndex = (arrayIndex + 1) % MAP_ARRAY_LENGTH; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static private class JNICriticalWorker implements Runnable { + private int count; + + private void doStep() { + byte[] inputArray = new byte[BYTE_ARRAY_LENGTH]; + for (int i = 0; i < inputArray.length; i += 1) { + inputArray[i] = (byte) (count + i); + } + + Deflater deflater = new Deflater(); + deflater.setInput(inputArray); + deflater.finish(); + + byte[] outputArray = new byte[2 * inputArray.length]; + deflater.deflate(outputArray); + + count += 1; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static class GCNotificationListener implements NotificationListener { + static private final double MIN_USED_PERCENT = 40.0; + + static private final List newGenPoolNames = Arrays.asList( + "G1 Eden Space", // OpenJDK G1GC: -XX:+UseG1GC + "PS Eden Space", // OpenJDK ParallelGC: -XX:+ParallelGC + "Par Eden Space", // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC + "Eden Space" // OpenJDK SerialGC: -XX:+UseSerialGC + // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC -XX:-UseParNewGC + ); + + @Override + public void handleNotification(Notification notification, Object handback) { + try { + if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + GarbageCollectionNotificationInfo info = + GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + + String gc_cause = info.getGcCause(); + + if (gc_cause.equals(TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE)) { + Map memory_before_gc = info.getGcInfo().getMemoryUsageBeforeGc(); + + for (String newGenPoolName : newGenPoolNames) { + MemoryUsage usage = memory_before_gc.get(newGenPoolName); + if (usage == null) continue; + + double startTime = ((double) info.getGcInfo().getStartTime()) / 1000.0; + long used = usage.getUsed(); + long committed = usage.getCommitted(); + long max = usage.getMax(); + double used_percent = (((double) used) / Math.max(committed, max)) * 100.0; + + System.out.printf("%6.3f: (%s) %d/%d/%d, %8.4f%% (%s)\n", + startTime, gc_cause, used, committed, max, used_percent, + ((used_percent < MIN_USED_PERCENT) ? TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + : TestExcessGCLockerCollectionsStringConstants.USED_OK)); + } + } + } + } catch (RuntimeException ex) { + System.err.println("Exception during notification processing:" + ex); + ex.printStackTrace(); + } + } + + public static boolean register() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + + // Get the list of MX + List gc_mxbeans = ManagementFactory.getGarbageCollectorMXBeans(); + + // Create the notification listener + GCNotificationListener gcNotificationListener = new GCNotificationListener(); + + for (GarbageCollectorMXBean gcbean : gc_mxbeans) { + // Add notification listener for the MXBean + mbeanServer.addNotificationListener(gcbean.getObjectName(), gcNotificationListener, null, null); + } + } catch (Exception ex) { + System.err.println("Exception during mbean registration:" + ex); + ex.printStackTrace(); + // We've failed to set up, terminate + return false; + } + + return true; + } + } + + static public Map largeMap; + + static public void main(String args[]) { + long durationSec = Long.parseLong(args[0]); + int allocThreadNum = Integer.parseInt(args[1]); + int jniCriticalThreadNum = Integer.parseInt(args[2]); + + println("Running for " + durationSec + " secs"); + + if (!GCNotificationListener.register()) { + println("failed to register GC notification listener"); + System.exit(-1); + } + + largeMap = populateMap(LARGE_MAP_SIZE); + + println("Starting " + allocThreadNum + " allocating threads"); + for (int i = 0; i < allocThreadNum; i += 1) { + new Thread(new AllocatingWorker()).start(); + } + + println("Starting " + jniCriticalThreadNum + " jni critical threads"); + for (int i = 0; i < jniCriticalThreadNum; i += 1) { + new Thread(new JNICriticalWorker()).start(); + } + + long durationMS = (long) (1000 * durationSec); + long start = System.currentTimeMillis(); + long now = start; + long soFar = now - start; + while (soFar < durationMS) { + try { + Thread.sleep(durationMS - soFar); + } catch (Exception e) { + } + now = System.currentTimeMillis(); + soFar = now - start; + } + println("Done."); + keepRunning = false; + } +} + +public class TestExcessGCLockerCollections { + private static final String USED_OK_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_OK + "\\)"; + private static final String USED_TOO_LOW_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + "\\)"; + + private static final String[] COMMON_OPTIONS = new String[] { + "-Xmx1G", "-Xms1G", "-Xmn256M" }; + + public static void main(String args[]) throws Exception { + if (args.length < 3) { + System.out.println("usage: TestExcessGCLockerCollections" + + " " + + " "); + throw new RuntimeException("Invalid arguments"); + } + + ArrayList finalArgs = new ArrayList(); + finalArgs.addAll(Arrays.asList(COMMON_OPTIONS)); + finalArgs.add(TestExcessGCLockerCollectionsAux.class.getName()); + finalArgs.addAll(Arrays.asList(args)); + + // GC and other options obtained from test framework. + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + true, finalArgs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + //System.out.println("------------- begin stdout ----------------"); + //System.out.println(output.getStdout()); + //System.out.println("------------- end stdout ----------------"); + output.stdoutShouldMatch(USED_OK_LINE); + output.stdoutShouldNotMatch(USED_TOO_LOW_LINE); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/test/runtime/8003720/VictimClassLoader.java openjdk-8-8u242-b08/=unpacked-tar2=/test/runtime/8003720/VictimClassLoader.java --- openjdk-8-8u232-b09/=unpacked-tar2=/test/runtime/8003720/VictimClassLoader.java 2019-10-10 10:32:42.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/test/runtime/8003720/VictimClassLoader.java 2020-01-15 09:13:39.000000000 +0000 @@ -22,6 +22,8 @@ * */ +import sun.misc.IOUtils; + public class VictimClassLoader extends ClassLoader { public static long counter = 0; @@ -72,8 +74,10 @@ } static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException { - // Warning here: - return sun.misc.IOUtils.readFully(in, len, true); + byte[] b = IOUtils.readAllBytes(in); + if (len != -1 && b.length != len) + throw new java.io.IOException("Expected:" + len + ", actual:" + b.length); + return b; } public void finalize() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar2=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar2=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar2=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar2=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar3=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar3=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar3=/.hg_archival.txt 2019-09-26 06:17:40.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar3=/.hg_archival.txt 2020-01-13 04:57:53.000000000 +0000 @@ -1,5 +1,4 @@ repo: 0961a4a211765fea071b8dac419003ee0c3d5973 -node: 5f799cd7fe51a1c0fab3c079f59b368853ba02c4 +node: b933b8903615c12824dc12ae493dc213e6f07c43 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar3=/.hgtags openjdk-8-8u242-b08/=unpacked-tar3=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar3=/.hgtags 2019-09-26 06:17:40.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar3=/.hgtags 2020-01-13 04:57:53.000000000 +0000 @@ -1004,6 +1004,16 @@ 28c25aedce2870fa12fc443560182b35091688d3 jdk8u232-b03 d8ecedf2321baf12d62c992f7e92bdfb52f48631 jdk8u232-b04 298981215ad0df664eebe5b44ce93c07c6d3e7c5 jdk8u232-b05 +60e3a82a99730978f4dcd67fcd7a52c6de5fdaba jdk8u242-b00 7261667ae4ff188688bf91a35779ccc05ac1d0e2 jdk8u232-b06 fb3b24b266a254727e88edaa3a7211a2de6c74db jdk8u232-b07 65b391f0ed666750478e3fc887c6a6c383190d30 jdk8u232-b08 +5f799cd7fe51a1c0fab3c079f59b368853ba02c4 jdk8u232-b09 +5f799cd7fe51a1c0fab3c079f59b368853ba02c4 jdk8u232-ga +3a911ec83c7e3786a95e3778dc459926b1c9775e jdk8u242-b01 +016be7bdaa27e14de8e40db8c67d0ab3997d5dc7 jdk8u242-b02 +6f53efc6747b8be967b6919ce83426924ae6b79e jdk8u242-b03 +b1722cc8c8d85ad8baac1469831a02b5c85f6c7a jdk8u242-b04 +c00877a0e915474c530fe45b68d8af8cbb245abf jdk8u242-b05 +a82b6ab00878ea389c4e03cbab0c01e7b2ffc257 jdk8u242-b06 +888c7a41a3ece3f502aa12b17fbd4625bc217c0f jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar3=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar3=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar3=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar3=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar4=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar4=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar4=/.hg_archival.txt 2019-05-31 17:58:10.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar4=/.hg_archival.txt 2020-01-13 04:57:48.000000000 +0000 @@ -1,5 +1,4 @@ repo: 6ce5f4757bde08f7470cbb9f0b46da8f2f3d4f56 -node: 6f9c0c731ab72a0f6e4085a0db9594e891de5e4f +node: eac8e0f4e575f35d0266340575d79f1102ef0502 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar4=/.hgtags openjdk-8-8u242-b08/=unpacked-tar4=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar4=/.hgtags 2019-05-31 17:58:10.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar4=/.hgtags 2020-01-13 04:57:48.000000000 +0000 @@ -1010,6 +1010,16 @@ 271cd29281ff780a5acd1feba5fba5066a5b4b16 jdk8u232-b03 cf6d611731058013acb5d3c1d3d123640289cbf9 jdk8u232-b04 2b9fdc450085129df45fff7c8d6604b6277b48c5 jdk8u232-b05 +7b44b5f468a471559b948c0672c6ab028968dccf jdk8u242-b00 be814fbd44e0803938cc6b6c600e4075ca3bdc9c jdk8u232-b06 0a5bd84fd43f074e58bb00117183e59f5e8a0595 jdk8u232-b07 764618a906e860888dc1fae5212d43be7abac4af jdk8u232-b08 +6f9c0c731ab72a0f6e4085a0db9594e891de5e4f jdk8u232-b09 +6f9c0c731ab72a0f6e4085a0db9594e891de5e4f jdk8u232-ga +6e9f5f2c620ae1a481aa8198d0507c3857bc6d42 jdk8u242-b01 +91cff4cef2095bbc8af71dec6357d6eb5524e0ce jdk8u242-b02 +616095b698d1c1c9a8c8a3517735be30be443207 jdk8u242-b03 +2199192fb5ecf001bfd3f3ad2fd5ae09ef7e3073 jdk8u242-b04 +81838c6f30bc08546c3cc9941583da81ed6dadb1 jdk8u242-b05 +77787fb589bb938de5cdf1462dee166cd6cd2722 jdk8u242-b06 +8bddae4d0a3d727b1f254ec8932fb2e505fd01de jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar4=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar4=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar4=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar4=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar5=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar5=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar5=/.hg_archival.txt 2019-09-26 06:17:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar5=/.hg_archival.txt 2020-01-13 04:57:44.000000000 +0000 @@ -1,5 +1,4 @@ repo: 55540e827aef970ecc010b7e06b912d991c8e3ce -node: 3cdc7d41905a2808bb01c3503e119073e9df0898 +node: bdd855313cfed15bb2d6bd567c0487313752bcb2 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar5=/.hgtags openjdk-8-8u242-b08/=unpacked-tar5=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar5=/.hgtags 2019-09-26 06:17:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar5=/.hgtags 2020-01-13 04:57:44.000000000 +0000 @@ -1046,6 +1046,16 @@ 8ce5d3e4f0b417996d0d962a3f8195501853b222 jdk8u232-b03 1447921be8023aec0684019e349a42e92f302fb7 jdk8u232-b04 836e5e2e10a55e1ed49ee002dbe9d974a4b32859 jdk8u232-b05 +75ad72ef4f68ca6a734ac2e44b9aadd8c10f8206 jdk8u242-b00 3fc52164727a38a74abceb9b9b84cd2396049c12 jdk8u232-b06 af5f5e2e07bc12472ffb52951120e14e19690b1a jdk8u232-b07 def9640e5d8213f650c128330161d9cdcd04d96b jdk8u232-b08 +3cdc7d41905a2808bb01c3503e119073e9df0898 jdk8u232-b09 +3cdc7d41905a2808bb01c3503e119073e9df0898 jdk8u232-ga +d4d4f7f07a863fd30db8911421ef45db4a6ad5dd jdk8u242-b01 +b3fbd77f16f6744939621dd68c18cb310f9a6e8d jdk8u242-b02 +89f67ddac3c9a8307156a7a1963d184ecd97efe0 jdk8u242-b03 +1835a96a04a6cf83449507245f5c4b12395d0cf5 jdk8u242-b04 +69e526db7430472a95cb9c43d928a8eb00faaf27 jdk8u242-b05 +751146fda0429aeb6501620cdcfa021d469613f1 jdk8u242-b06 +72d4f7e239eec808290ee6e1ab99dfab88d66150 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar5=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar5=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar5=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar5=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar7=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar7=/.hg_archival.txt 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/.hg_archival.txt 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,4 @@ repo: 37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 -node: 5456f24496f43f72b0cf4f0db3a73ea49c33f94f +node: c63c2923e1f99c1f350bd24b42daf885023f18b7 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/.hgtags openjdk-8-8u242-b08/=unpacked-tar7=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar7=/.hgtags 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/.hgtags 2020-01-15 20:05:09.000000000 +0000 @@ -1005,6 +1005,16 @@ 60eca04567a6d214aa60dd16306f4854bd41b273 jdk8u232-b03 3ef3348195ffeb3c268af4a43928f2f09c5fa83a jdk8u232-b04 6d60b8cf1bd4a5fa371b1ddad9d186ff546b25f5 jdk8u232-b05 +1e8cdf311133ecde0ccae37e6137e49adc6164fb jdk8u242-b00 5d57817931e1f5b6a460158342f132ea348e14ef jdk8u232-b06 3560e0ebe876ce658c5261070fe728e47994210f jdk8u232-b07 69c4f673b33e255599d2aa257fa50fd8b48b7b95 jdk8u232-b08 +5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-b09 +5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-ga +d32fc856e071ff49c8a4c94682caad57f6c6874f jdk8u242-b01 +2b292ab0ed9af9aa8aab27b1a80daa3509a050ba jdk8u242-b02 +2f564a16517d678f31a3fa7352e16702e48c417d jdk8u242-b03 +8163e59959ed5462891f2b1db7bc0fa2af1de0a6 jdk8u242-b04 +b2865f7f557fcaec84445b034b2de2b27456b6c5 jdk8u242-b05 +0d27e60569f7cf85cbdb0a83436e772e9256b5b0 jdk8u242-b06 +034a65a05bfbfb06e14d3d39efa0c9f27683573a jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java openjdk-8-8u242-b08/=unpacked-tar7=/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java --- openjdk-8-8u232-b09/=unpacked-tar7=/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java 2020-01-15 20:05:09.000000000 +0000 @@ -4,7 +4,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 -Nru openjdk-8-8u232-b09/=unpacked-tar7=/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c openjdk-8-8u242-b08/=unpacked-tar7=/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c --- openjdk-8-8u232-b09/=unpacked-tar7=/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c 2020-01-15 20:05:09.000000000 +0000 @@ -4,7 +4,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 -Nru openjdk-8-8u232-b09/=unpacked-tar7=/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c openjdk-8-8u242-b08/=unpacked-tar7=/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c --- openjdk-8-8u232-b09/=unpacked-tar7=/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c 2020-01-15 20:05:09.000000000 +0000 @@ -4,7 +4,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 -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,8 +48,9 @@ native void validate(int xoff, int yoff, int width, int height, boolean isOpaque); - private native void initOps(long pConfigInfo, long pPeerData, long layerPtr, - int xoff, int yoff, boolean isOpaque); + private native void initOps(OGLGraphicsConfig gc, long pConfigInfo, + long pPeerData, long layerPtr, int xoff, + int yoff, boolean isOpaque); protected native boolean initPbuffer(long pData, long pConfigInfo, boolean isOpaque, int width, int height); @@ -77,7 +78,7 @@ pPeerData = pView.getAWTView(); isOpaque = pView.isOpaque(); } - initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque); + initOps(gc, pConfigInfo, pPeerData, 0, 0, 0, isOpaque); } protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc, @@ -93,7 +94,7 @@ layerPtr = layer.getPointer(); isOpaque = layer.isOpaque(); } - initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque); + initOps(gc, pConfigInfo, 0, layerPtr, 0, 0, isOpaque); } @Override //SurfaceData diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser --- openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser 2020-01-15 20:05:09.000000000 +0000 @@ -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 -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/sun/awt/CGraphicsDevice.m openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/sun/awt/CGraphicsDevice.m --- openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/sun/awt/CGraphicsDevice.m 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/sun/awt/CGraphicsDevice.m 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,16 +94,18 @@ static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) { CGDisplayModeRef bestGuess = NULL; CFIndex numModes = CFArrayGetCount(allModes), n; - int thisBpp = 0; + for(n = 0; n < numModes; n++ ) { CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n); if(cRef == NULL) { continue; } CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef); - thisBpp = getBPPFromModeString(modeString); + int thisBpp = getBPPFromModeString(modeString); CFRelease(modeString); - if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) { + int thisH = (int)CGDisplayModeGetHeight(cRef); + int thisW = (int)CGDisplayModeGetWidth(cRef); + if (thisBpp != bpp || thisH != h || thisW != w) { // One of the key parameters does not match continue; } @@ -114,11 +116,12 @@ // Refresh rate might be 0 in display mode and we ask for specific display rate // but if we do not find exact match then 0 refresh rate might be just Ok - if (CGDisplayModeGetRefreshRate(cRef) == refrate) { + int thisRefrate = (int)CGDisplayModeGetRefreshRate(cRef); + if (thisRefrate == refrate) { // Exact match return cRef; } - if (CGDisplayModeGetRefreshRate(cRef) == 0) { + if (thisRefrate == 0) { // Not exactly what was asked for, but may fit our needs if we don't find an exact match bestGuess = cRef; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m --- openjdk-8-8u232-b09/=unpacked-tar7=/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m 2020-01-15 20:05:09.000000000 +0000 @@ -145,31 +145,6 @@ } /** - * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo - * associated with the given OGLSDOps. This method can be called from - * shared code to retrieve the native GraphicsConfig data in a platform- - * independent manner. - */ -jlong -OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo"); - - if (oglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null"); - return 0L; - } - - CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps; - if (cglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null"); - return 0L; - } - - return ptr_to_jlong(cglsdo->configInfo); -} - -/** * Makes the given GraphicsConfig's context current to its associated * "scratch" surface. If there is a problem making the context current, * this method will return NULL; otherwise, returns a pointer to the @@ -411,7 +386,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_opengl_CGLSurfaceData_initOps - (JNIEnv *env, jobject cglsd, + (JNIEnv *env, jobject cglsd, jobject gc, jlong pConfigInfo, jlong pPeerData, jlong layerPtr, jint xoff, jint yoff, jboolean isOpaque) { @@ -419,8 +394,22 @@ J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData)); J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff); + gc = (*env)->NewGlobalRef(env, gc); + if (gc == NULL) { + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + return; + } + OGLSDOps *oglsdo = (OGLSDOps *) SurfaceData_InitOps(env, cglsd, sizeof(OGLSDOps)); + if (oglsdo == NULL) { + (*env)->DeleteGlobalRef(env, gc); + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + return; + } + // later the graphicsConfig will be used for deallocation of oglsdo + oglsdo->graphicsConfig = gc; + CGLSDOps *cglsdo = (CGLSDOps *)malloc(sizeof(CGLSDOps)); if (cglsdo == NULL) { JNU_ThrowOutOfMemoryError(env, "creating native cgl ops"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/GHASH.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/GHASH.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/GHASH.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/GHASH.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -62,14 +62,16 @@ private static final int AES_BLOCK_SIZE = 16; - // Multiplies state0, state1 by V0, V1. - private void blockMult(long V0, long V1) { + // Multiplies state[0], state[1] by subkeyH[0], subkeyH[1]. + private static void blockMult(long[] st, long[] subH) { long Z0 = 0; long Z1 = 0; + long V0 = subH[0]; + long V1 = subH[1]; long X; - // Separate loops for processing state0 and state1. - X = state0; + // Separate loops for processing state[0] and state[1]. + X = st[0]; for (int i = 0; i < 64; i++) { // Zi+1 = Zi if bit i of x is 0 long mask = X >> 63; @@ -89,7 +91,7 @@ X <<= 1; } - X = state1; + X = st[1]; for (int i = 64; i < 127; i++) { // Zi+1 = Zi if bit i of x is 0 long mask = X >> 63; @@ -115,15 +117,18 @@ Z1 ^= V1 & mask; // Save result. - state0 = Z0; - state1 = Z1; + st[0] = Z0; + st[1] = Z1; + } + /* subkeyH and state are stored in long[] for GHASH intrinsic use */ + // hash subkey H; should not change after the object has been constructed - private final long subkeyH0, subkeyH1; + private final long[] subkeyH; // buffer for storing hash - private long state0, state1; + private final long[] state; // variables for save/restore calls private long stateSave0, stateSave1; @@ -141,8 +146,10 @@ if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) { throw new ProviderException("Internal error"); } - this.subkeyH0 = getLong(subkeyH, 0); - this.subkeyH1 = getLong(subkeyH, 8); + state = new long[2]; + this.subkeyH = new long[2]; + this.subkeyH[0] = getLong(subkeyH, 0); + this.subkeyH[1] = getLong(subkeyH, 8); } /** @@ -151,33 +158,30 @@ * this object for different data w/ the same H. */ void reset() { - state0 = 0; - state1 = 0; + state[0] = 0; + state[1] = 0; } /** * Save the current snapshot of this GHASH object. */ void save() { - stateSave0 = state0; - stateSave1 = state1; + stateSave0 = state[0]; + stateSave1 = state[1]; } /** * Restores this object using the saved snapshot. */ void restore() { - state0 = stateSave0; - state1 = stateSave1; + state[0] = stateSave0; + state[1] = stateSave1; } - private void processBlock(byte[] data, int ofs) { - if (data.length - ofs < AES_BLOCK_SIZE) { - throw new RuntimeException("need complete block"); - } - state0 ^= getLong(data, ofs); - state1 ^= getLong(data, ofs + 8); - blockMult(subkeyH0, subkeyH1); + private static void processBlock(byte[] data, int ofs, long[] st, long[] subH) { + st[0] ^= getLong(data, ofs); + st[1] ^= getLong(data, ofs + 8); + blockMult(st, subH); } void update(byte[] in) { @@ -185,22 +189,57 @@ } void update(byte[] in, int inOfs, int inLen) { - if (inLen - inOfs > in.length) { - throw new RuntimeException("input length out of bound"); + if (inLen == 0) { + return; + } + ghashRangeCheck(in, inOfs, inLen, state, subkeyH); + processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyH); + } + + private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subH) { + if (inLen < 0) { + throw new RuntimeException("invalid input length: " + inLen); + } + if (inOfs < 0) { + throw new RuntimeException("invalid offset: " + inOfs); + } + if (inLen > in.length - inOfs) { + throw new RuntimeException("input length out of bound: " + + inLen + " > " + (in.length - inOfs)); } if (inLen % AES_BLOCK_SIZE != 0) { - throw new RuntimeException("input length unsupported"); + throw new RuntimeException("input length/block size mismatch: " + + inLen); } - for (int i = inOfs; i < (inOfs + inLen); i += AES_BLOCK_SIZE) { - processBlock(in, i); + // These two checks are for C2 checking + if (st.length != 2) { + throw new RuntimeException("internal state has invalid length: " + + st.length); + } + if (subH.length != 2) { + throw new RuntimeException("internal subkeyH has invalid length: " + + subH.length); + } + } + /* + * This is an intrinsified method. The method's argument list must match + * the hotspot signature. This method and methods called by it, cannot + * throw exceptions or allocate arrays as it will breaking intrinsics + */ + private static void processBlocks(byte[] data, int inOfs, int blocks, long[] st, long[] subH) { + int offset = inOfs; + while (blocks > 0) { + processBlock(data, offset, st, subH); + blocks--; + offset += AES_BLOCK_SIZE; } } byte[] digest() { byte[] result = new byte[AES_BLOCK_SIZE]; - putLong(result, 0, state0); - putLong(result, 8, state1); + putLong(result, 0, state[0]); + putLong(result, 8, state[1]); reset(); return result; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/JceKeyStore.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/JceKeyStore.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/JceKeyStore.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/crypto/provider/JceKeyStore.java 2020-01-15 20:05:09.000000000 +0000 @@ -43,6 +43,7 @@ import java.security.cert.CertificateException; import javax.crypto.SealedObject; +import sun.misc.IOUtils; import sun.misc.ObjectInputFilter; /** @@ -70,7 +71,7 @@ private static final class PrivateKeyEntry { Date date; // the creation date of this entry byte[] protectedKey; - Certificate chain[]; + Certificate[] chain; }; // Secret key @@ -738,23 +739,11 @@ entry.date = new Date(dis.readLong()); // read the private key - try { - entry.protectedKey = new byte[dis.readInt()]; - } catch (OutOfMemoryError e) { - throw new IOException("Keysize too big"); - } - dis.readFully(entry.protectedKey); + entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt()); // read the certificate chain int numOfCerts = dis.readInt(); - try { - if (numOfCerts > 0) { - entry.chain = new Certificate[numOfCerts]; - } - } catch (OutOfMemoryError e) { - throw new IOException("Too many certificates in " - + "chain"); - } + List tmpCerts = new ArrayList<>(); for (int j = 0; j < numOfCerts; j++) { if (xVersion == 2) { // read the certificate type, and instantiate a @@ -762,27 +751,24 @@ // existing factory if possible) String certType = dis.readUTF(); if (cfs.containsKey(certType)) { - // reuse certificate factory + // reuse certificate factory cf = cfs.get(certType); } else { - // create new certificate factory + // create new certificate factory cf = CertificateFactory.getInstance( certType); - // store the certificate factory so we can - // reuse it later + // store the certificate factory so we can + // reuse it later cfs.put(certType, cf); } } // instantiate the certificate - try { - encoded = new byte[dis.readInt()]; - } catch (OutOfMemoryError e) { - throw new IOException("Certificate too big"); - } - dis.readFully(encoded); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); - entry.chain[j] = cf.generateCertificate(bais); + tmpCerts.add(cf.generateCertificate(bais)); } + entry.chain = tmpCerts.toArray( + new Certificate[numOfCerts]); // Add the entry to the list entries.put(alias, entry); @@ -814,12 +800,7 @@ cfs.put(certType, cf); } } - try { - encoded = new byte[dis.readInt()]; - } catch (OutOfMemoryError e) { - throw new IOException("Certificate too big"); - } - dis.readFully(encoded); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); entry.cert = cf.generateCertificate(bais); @@ -870,18 +851,14 @@ * with */ if (password != null) { - byte computed[], actual[]; - computed = md.digest(); - actual = new byte[computed.length]; - dis.readFully(actual); - for (int i = 0; i < computed.length; i++) { - if (computed[i] != actual[i]) { - throw new IOException( + byte[] computed = md.digest(); + byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length); + if (!MessageDigest.isEqual(computed, actual)) { + throw new IOException( "Keystore was tampered with, or " + "password was incorrect", - new UnrecoverableKeyException( - "Password verification failed")); - } + new UnrecoverableKeyException( + "Password verification failed")); } } } finally { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java 2020-01-15 20:05:09.000000000 +0000 @@ -123,6 +123,13 @@ return e; } + private Entry checkValid(Entry e) { + if (e == INVALID_ENTRY) { + throw new IllegalStateException("Invalid constant pool reference"); + } + return e; + } + /** Throw a ClassFormatException if the entry does not match the expected tag type. */ private Entry checkTag(Entry e, byte tag) throws ClassFormatException { if (e == null || !e.tagMatches(tag)) { @@ -225,6 +232,29 @@ return null; // OK } + // use this identity for invalid references + private static final Entry INVALID_ENTRY = new Entry((byte) -1) { + @Override + public boolean equals(Object o) { + throw new IllegalStateException("Should not call this"); + } + + @Override + protected int computeValueHash() { + throw new IllegalStateException("Should not call this"); + } + + @Override + public int compareTo(Object o) { + throw new IllegalStateException("Should not call this"); + } + + @Override + public String stringValue() { + throw new IllegalStateException("Should not call this"); + } + }; + void readConstantPool() throws IOException { int length = in.readUnsignedShort(); //System.err.println("reading CP, length="+length); @@ -233,7 +263,7 @@ int fptr = 0; Entry[] cpMap = new Entry[length]; - cpMap[0] = null; + cpMap[0] = INVALID_ENTRY; for (int i = 1; i < length; i++) { //System.err.println("reading CP elt, i="+i); int tag = in.readByte(); @@ -254,13 +284,13 @@ case CONSTANT_Long: { cpMap[i] = ConstantPool.getLiteralEntry(in.readLong()); - cpMap[++i] = null; + cpMap[++i] = INVALID_ENTRY; } break; case CONSTANT_Double: { cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble()); - cpMap[++i] = null; + cpMap[++i] = INVALID_ENTRY; } break; @@ -315,7 +345,7 @@ int ref2 = fixups[fi++]; if (verbose > 3) Utils.log.fine(" cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}"); - if (ref >= 0 && cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) { + if (ref >= 0 && checkValid(cpMap[ref]) == null || ref2 >= 0 && checkValid(cpMap[ref2]) == null) { // Defer. fixups[fptr++] = cpi; fixups[fptr++] = tag; @@ -364,7 +394,6 @@ cls.cpMap = cpMap; } - private /*non-static*/ class UnresolvedEntry extends Entry { final Object[] refsOrIndexes; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/jndi/ldap/Connection.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/jndi/ldap/Connection.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/jndi/ldap/Connection.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/jndi/ldap/Connection.java 2020-01-15 20:05:09.000000000 +0000 @@ -47,8 +47,6 @@ import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; -import sun.misc.IOUtils; - /** * A thread that creates a connection to an LDAP server. * After the connection, the thread reads from the connection. @@ -886,7 +884,7 @@ } // read in seqlen bytes - byte[] left = IOUtils.readFully(in, seqlen, false); + byte[] left = readFully(in, seqlen); inbuf = Arrays.copyOf(inbuf, offset + left.length); System.arraycopy(left, 0, inbuf, offset, left.length); offset += left.length; @@ -981,6 +979,31 @@ } } + private static byte[] readFully(InputStream is, int length) + throws IOException + { + byte[] buf = new byte[Math.min(length, 8192)]; + int nread = 0; + while (nread < length) { + int bytesToRead; + if (nread >= buf.length) { // need to allocate a larger buffer + bytesToRead = Math.min(length - nread, buf.length + 8192); + if (buf.length < nread + bytesToRead) { + buf = Arrays.copyOf(buf, nread + bytesToRead); + } + } else { + bytesToRead = buf.length - nread; + } + int count = is.read(buf, nread, bytesToRead); + if (count < 0) { + if (buf.length != nread) + buf = Arrays.copyOf(buf, nread); + break; + } + nread += count; + } + return buf; + } // This code must be uncommented to run the LdapAbandonTest. /*public void sendSearchReqs(String dn, int numReqs) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2020-01-15 20:05:09.000000000 +0000 @@ -123,8 +123,9 @@ * must also be set to true; Otherwise a configuration error will * be returned. *
renewTGT:
- *
Set this to true, if you want to renew - * the TGT. If this is set, useTicketCache must also be + *
Set this to true, if you want to renew the TGT when it's more than + * half-way expired (the time until expiration is less than the time + * since start time). If this is set, {@code useTicketCache} must also be * set to true; otherwise a configuration error will be returned.
*
doNotPrompt:
*
Set this to true if you do not want to be @@ -665,22 +666,21 @@ (principal, ticketCacheName); if (cred != null) { - // check to renew credentials - if (!isCurrent(cred)) { - if (renewTGT) { - Credentials newCred = renewCredentials(cred); - if (newCred != null) { - newCred.setProxy(cred.getProxy()); - } + if (renewTGT && isOld(cred)) { + // renew if ticket is old. + Credentials newCred = renewCredentials(cred); + if (newCred != null) { + newCred.setProxy(cred.getProxy()); cred = newCred; - } else { - // credentials have expired - cred = null; - if (debug) - System.out.println("Credentials are" + - " no longer valid"); } } + if (!isCurrent(cred)) { + // credentials have expired + cred = null; + if (debug) + System.out.println("Credentials are" + + " no longer valid"); + } } if (cred != null) { @@ -988,7 +988,7 @@ } } - private boolean isCurrent(Credentials creds) + private static boolean isCurrent(Credentials creds) { Date endTime = creds.getEndTime(); if (endTime != null) { @@ -997,6 +997,23 @@ return true; } + private static boolean isOld(Credentials creds) + { + Date endTime = creds.getEndTime(); + if (endTime != null) { + Date authTime = creds.getAuthTime(); + long now = System.currentTimeMillis(); + if (authTime != null) { + // pass the mid between auth and end + return now - authTime.getTime() > endTime.getTime() - now; + } else { + // will expire in less than 2 hours + return now <= endTime.getTime() - 1000*3600*2L; + } + } + return false; + } + private Credentials renewCredentials(Credentials creds) { Credentials lcreds; @@ -1004,6 +1021,10 @@ if (!creds.isRenewable()) throw new RefreshFailedException("This ticket" + " is not renewable"); + if (creds.getRenewTill() == null) { + // Renewable ticket without renew-till. Illegal and ignored. + return creds; + } if (System.currentTimeMillis() > cred.getRenewTill().getTime()) throw new RefreshFailedException("This ticket is past " + "its last renewal time."); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,8 +73,12 @@ } try { - MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); + MessageProp msgProp = new MessageProp(JGSS_QOP, false); byte[] answer = secCtx.unwrap(incoming, start, len, msgProp); + if (privacy && !msgProp.getPrivacy()) { + throw new SaslException("Privacy not protected"); + } + checkMessageProp("", msgProp); if (logger.isLoggable(Level.FINEST)) { traceOutput(myClassName, "KRB501:Unwrap", "incoming: ", incoming, start, len); @@ -128,4 +132,20 @@ protected void finalize() throws Throwable { dispose(); } + + void checkMessageProp(String label, MessageProp msgProp) + throws SaslException { + if (msgProp.isDuplicateToken()) { + throw new SaslException(label + "Duplicate token"); + } + if (msgProp.isGapToken()) { + throw new SaslException(label + "Gap token"); + } + if (msgProp.isOldToken()) { + throw new SaslException(label + "Old token"); + } + if (msgProp.isUnseqToken()) { + throw new SaslException(label + "Token not in sequence"); + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -230,8 +230,10 @@ // Received S1 (security layer, server max recv size) + MessageProp msgProp = new MessageProp(false); byte[] gssOutToken = secCtx.unwrap(challengeData, 0, - challengeData.length, new MessageProp(0, false)); + challengeData.length, msgProp); + checkMessageProp("Handshake failure: ", msgProp); // First octet is a bit-mask specifying the protections // supported by the server diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -250,8 +250,10 @@ try { // Expecting 4 octets from client selected protection // and client's receive buffer size + MessageProp msgProp = new MessageProp(false); byte[] gssOutToken = secCtx.unwrap(responseData, 0, - responseData.length, new MessageProp(0, false)); + responseData.length, msgProp); + checkMessageProp("Handshake failure: ", msgProp); if (logger.isLoggable(Level.FINER)) { traceOutput(MY_CLASS_NAME, "doHandshake2", diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/awt/color/ICC_Profile.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/awt/color/ICC_Profile.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/awt/color/ICC_Profile.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/awt/color/ICC_Profile.java 2020-01-15 20:05:09.000000000 +0000 @@ -43,7 +43,9 @@ import sun.java2d.cmm.ProfileDeferralMgr; import sun.java2d.cmm.ProfileDeferralInfo; import sun.java2d.cmm.ProfileActivator; +import sun.misc.IOUtils; +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -1019,42 +1021,25 @@ static byte[] getProfileDataFromStream(InputStream s) throws IOException { - byte profileData[]; - int profileSize; - byte header[] = new byte[128]; - int bytestoread = 128; - int bytesread = 0; - int n; - - while (bytestoread != 0) { - if ((n = s.read(header, bytesread, bytestoread)) < 0) { - return null; - } - bytesread += n; - bytestoread -= n; - } + BufferedInputStream bis = new BufferedInputStream(s); + bis.mark(128); + + byte[] header = IOUtils.readNBytes(bis, 128); if (header[36] != 0x61 || header[37] != 0x63 || header[38] != 0x73 || header[39] != 0x70) { return null; /* not a valid profile */ } - profileSize = ((header[0] & 0xff) << 24) | - ((header[1] & 0xff) << 16) | - ((header[2] & 0xff) << 8) | - (header[3] & 0xff); - profileData = new byte[profileSize]; - System.arraycopy(header, 0, profileData, 0, 128); - bytestoread = profileSize - 128; - bytesread = 128; - while (bytestoread != 0) { - if ((n = s.read(profileData, bytesread, bytestoread)) < 0) { - return null; - } - bytesread += n; - bytestoread -= n; + int profileSize = ((header[0] & 0xff) << 24) | + ((header[1] & 0xff) << 16) | + ((header[2] & 0xff) << 8) | + (header[3] & 0xff); + bis.reset(); + try { + return IOUtils.readNBytes(bis, profileSize); + } catch (OutOfMemoryError e) { + throw new IOException("Color profile is too big"); } - - return profileData; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/beans/beancontext/BeanContextSupport.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/beans/beancontext/BeanContextSupport.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/beans/beancontext/BeanContextSupport.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/beans/beancontext/BeanContextSupport.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1024,18 +1024,8 @@ int count = serializable; while (count-- > 0) { - Object child = null; - BeanContextSupport.BCSChild bscc = null; - - try { - child = ois.readObject(); - bscc = (BeanContextSupport.BCSChild)ois.readObject(); - } catch (IOException ioe) { - continue; - } catch (ClassNotFoundException cnfe) { - continue; - } - + Object child = ois.readObject(); + BCSChild bscc = (BCSChild) ois.readObject(); synchronized(child) { BeanContextChild bcc = null; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/io/FilePermission.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/io/FilePermission.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/io/FilePermission.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/io/FilePermission.java 2020-01-15 20:05:09.000000000 +0000 @@ -46,8 +46,11 @@ * the file separator character, File.separatorChar) indicates * all the files and directories contained in that directory. A pathname * that ends with "/-" indicates (recursively) all files - * and subdirectories contained in that directory. A pathname consisting of - * the special token "<<ALL FILES>>" matches any file. + * and subdirectories contained in that directory. Such a pathname is called + * a wildcard pathname. Otherwise, it's a simple pathname. + *

+ * A pathname consisting of the special token {@literal "<>"} + * matches any file. *

* Note: A pathname consisting of a single "*" indicates all the files * in the current directory, while a pathname consisting of a single "-" @@ -80,7 +83,7 @@ *

* Be careful when granting FilePermissions. Think about the implications * of granting read and especially write access to various files and - * directories. The "<<ALL FILES>>" permission with write action is + * directories. The {@literal "<>"} permission with write action is * especially dangerous. This grants permission to write to the entire * file system. One thing this effectively allows is replacement of the * system binary, including the JVM runtime environment. @@ -156,6 +159,7 @@ private transient String cpath; + private transient boolean allFiles; // whether this is <> private transient boolean invalid; // whether input path is invalid // static Strings used by init(int mask) @@ -207,6 +211,7 @@ this.mask = mask; if (cpath.equals("<>")) { + allFiles = true; directory = true; recursive = true; cpath = ""; @@ -335,6 +340,23 @@ * "/tmp/*" encompasses all files in the "/tmp" directory, * including the one named "foo". * + *

+ * Precisely, a simple pathname implies another simple pathname + * if and only if they are equal. A simple pathname never implies + * a wildcard pathname. A wildcard pathname implies another wildcard + * pathname if and only if all simple pathnames implied by the latter + * are implied by the former. A wildcard pathname implies a simple + * pathname if and only if + *

    + *
  • if the wildcard flag is "*", the simple pathname's path + * must be right inside the wildcard pathname's path. + *
  • if the wildcard flag is "-", the simple pathname's path + * must be recursively inside the wildcard pathname's path. + *
+ *

+ * {@literal "<>"} implies every other pathname. No pathname, + * except for {@literal "<>"} itself, implies + * {@literal "<>"}. * * @param p the permission to check against. * @@ -366,9 +388,15 @@ if (this == that) { return true; } + if (allFiles) { + return true; + } if (this.invalid || that.invalid) { return false; } + if (that.allFiles) { + return false; + } if (this.directory) { if (this.recursive) { // make sure that.path is longer then path so @@ -415,6 +443,10 @@ * Checks two FilePermission objects for equality. Checks that obj is * a FilePermission, and has the same pathname and actions as this object. * + * @implNote More specifically, two pathnames are the same if and only if + * they have the same wildcard flag and their + * {@code npath} are equal. Or they are both {@literal "<>"}. + * * @param obj the object we are testing for equality with this object. * @return true if obj is a FilePermission, and has the same * pathname and actions as this FilePermission object, @@ -433,6 +465,7 @@ return false; } return (this.mask == that.mask) && + (this.allFiles == that.allFiles) && this.cpath.equals(that.cpath) && (this.directory == that.directory) && (this.recursive == that.recursive); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/io/ObjectInputStream.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/io/ObjectInputStream.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/io/ObjectInputStream.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/io/ObjectInputStream.java 2020-01-15 20:05:09.000000000 +0000 @@ -419,16 +419,50 @@ * @throws IOException Any of the usual Input/Output related exceptions. */ public final Object readObject() + throws IOException, ClassNotFoundException { + return readObject(Object.class); + } + + /** + * Reads a String and only a string. + * + * @return the String read + * @throws EOFException If end of file is reached. + * @throws IOException If other I/O error has occurred. + */ + private String readString() throws IOException { + try { + return (String) readObject(String.class); + } catch (ClassNotFoundException cnf) { + throw new IllegalStateException(cnf); + } + } + + /** + * Internal method to read an object from the ObjectInputStream of the expected type. + * Called only from {@code readObject()} and {@code readString()}. + * Only {@code Object.class} and {@code String.class} are supported. + * + * @param type the type expected; either Object.class or String.class + * @return an object of the type + * @throws IOException Any of the usual Input/Output related exceptions. + * @throws ClassNotFoundException Class of a serialized object cannot be + * found. + */ + private final Object readObject(Class type) throws IOException, ClassNotFoundException { if (enableOverride) { return readObjectOverride(); } + if (! (type == Object.class || type == String.class)) + throw new AssertionError("internal error"); + // if nested read, passHandle contains handle of enclosing object int outerHandle = passHandle; try { - Object obj = readObject0(false); + Object obj = readObject0(type, false); handles.markDependency(outerHandle, passHandle); ClassNotFoundException ex = handles.lookupException(passHandle); if (ex != null) { @@ -518,7 +552,7 @@ // if nested read, passHandle contains handle of enclosing object int outerHandle = passHandle; try { - Object obj = readObject0(true); + Object obj = readObject0(Object.class, true); handles.markDependency(outerHandle, passHandle); ClassNotFoundException ex = handles.lookupException(passHandle); if (ex != null) { @@ -1517,8 +1551,10 @@ /** * Underlying readObject implementation. + * @param type a type expected to be deserialized; non-null + * @param unshared true if the object can not be a reference to a shared object, otherwise false */ - private Object readObject0(boolean unshared) throws IOException { + private Object readObject0(Class type, boolean unshared) throws IOException { boolean oldMode = bin.getBlockDataMode(); if (oldMode) { int remain = bin.currentBlockRemaining(); @@ -1550,13 +1586,20 @@ return readNull(); case TC_REFERENCE: - return readHandle(unshared); + // check the type of the existing object + return type.cast(readHandle(unshared)); case TC_CLASS: + if (type == String.class) { + throw new ClassCastException("Cannot cast a class to java.lang.String"); + } return readClass(unshared); case TC_CLASSDESC: case TC_PROXYCLASSDESC: + if (type == String.class) { + throw new ClassCastException("Cannot cast a class to java.lang.String"); + } return readClassDesc(unshared); case TC_STRING: @@ -1564,15 +1607,27 @@ return checkResolve(readString(unshared)); case TC_ARRAY: + if (type == String.class) { + throw new ClassCastException("Cannot cast an array to java.lang.String"); + } return checkResolve(readArray(unshared)); case TC_ENUM: + if (type == String.class) { + throw new ClassCastException("Cannot cast an enum to java.lang.String"); + } return checkResolve(readEnum(unshared)); case TC_OBJECT: + if (type == String.class) { + throw new ClassCastException("Cannot cast an object to java.lang.String"); + } return checkResolve(readOrdinaryObject(unshared)); case TC_EXCEPTION: + if (type == String.class) { + throw new ClassCastException("Cannot cast an exception to java.lang.String"); + } IOException ex = readFatalException(); throw new WriteAbortedException("writing aborted", ex); @@ -1947,7 +2002,7 @@ if (ccl == null) { for (int i = 0; i < len; i++) { - readObject0(false); + readObject0(Object.class, false); } } else if (ccl.isPrimitive()) { if (ccl == Integer.TYPE) { @@ -1972,7 +2027,7 @@ } else { Object[] oa = (Object[]) array; for (int i = 0; i < len; i++) { - oa[i] = readObject0(false); + oa[i] = readObject0(Object.class, false); handles.markDependency(arrayHandle, passHandle); } } @@ -2250,7 +2305,7 @@ return; default: - readObject0(false); + readObject0(Object.class, false); break; } } @@ -2284,7 +2339,7 @@ int numPrimFields = fields.length - objVals.length; for (int i = 0; i < objVals.length; i++) { ObjectStreamField f = fields[numPrimFields + i]; - objVals[i] = readObject0(f.isUnshared()); + objVals[i] = readObject0(Object.class, f.isUnshared()); if (f.getField() != null) { handles.markDependency(objHandle, passHandle); } @@ -2305,7 +2360,7 @@ throw new InternalError(); } clear(); - return (IOException) readObject0(false); + return (IOException) readObject0(Object.class, false); } /** @@ -2449,7 +2504,7 @@ int numPrimFields = fields.length - objVals.length; for (int i = 0; i < objVals.length; i++) { objVals[i] = - readObject0(fields[numPrimFields + i].isUnshared()); + readObject0(Object.class, fields[numPrimFields + i].isUnshared()); objHandles[i] = passHandle; } passHandle = oldHandle; @@ -3403,7 +3458,15 @@ * utflen bytes. */ private String readUTFBody(long utflen) throws IOException { - StringBuilder sbuf = new StringBuilder(); + StringBuilder sbuf; + if (utflen > 0 && utflen < Integer.MAX_VALUE) { + // a reasonable initial capacity based on the UTF length + int initialCapacity = Math.min((int)utflen, 0xFFFF); + sbuf = new StringBuilder(initialCapacity); + } else { + sbuf = new StringBuilder(); + } + if (!blkmode) { end = pos = 0; } @@ -3918,5 +3981,6 @@ } static { SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator); + SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/ClassLoader.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/ClassLoader.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/ClassLoader.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/ClassLoader.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1467,6 +1468,17 @@ } } + /* + * Initialize default paths for native libraries search. + * Must be done early as JDK may load libraries during bootstrap. + * + * @see java.lang.System#initPhase1 + */ + static void initLibraryPaths() { + usr_paths = initializePath("java.library.path"); + sys_paths = initializePath("sun.boot.library.path"); + } + // Returns true if the specified class loader can be found in this class // loader's delegation chain. boolean isAncestor(ClassLoader cl) { @@ -1809,10 +1821,9 @@ boolean isAbsolute) { ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); - if (sys_paths == null) { - usr_paths = initializePath("java.library.path"); - sys_paths = initializePath("sun.boot.library.path"); - } + assert sys_paths != null : "should be initialized at this point"; + assert usr_paths != null : "should be initialized at this point"; + if (isAbsolute) { if (loadLibrary0(fromClass, new File(name))) { return; @@ -1902,13 +1913,14 @@ name + " already loaded in another classloader"); } - /* If the library is being loaded (must be by the same thread, - * because Runtime.load and Runtime.loadLibrary are - * synchronous). The reason is can occur is that the JNI_OnLoad - * function can cause another loadLibrary invocation. + /* + * When a library is being loaded, JNI_OnLoad function can cause + * another loadLibrary invocation that should succeed. * - * Thus we can use a static stack to hold the list of libraries - * we are loading. + * We use a static stack to hold the list of libraries we are + * loading because this can happen only when called by the + * same thread because Runtime.load and Runtime.loadLibrary + * are synchronous. * * If there is a pending load operation for the library, we * immediately return success; otherwise, we raise diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/reflect/Executable.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/reflect/Executable.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/reflect/Executable.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/reflect/Executable.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, 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 @@ -588,22 +588,29 @@ return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Executable root = getRoot(); - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - getAnnotationBytes(), - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Executable root = getRoot(); + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + getAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass() + ); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } /** diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/reflect/Field.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/reflect/Field.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/reflect/Field.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/reflect/Field.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1139,21 +1139,28 @@ return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Field root = this.root; - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, - sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Field root = this.root; + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + annotations, + sun.misc.SharedSecrets.getJavaLangAccess() + .getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } private native byte[] getTypeAnnotationBytes0(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/Runtime.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/Runtime.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/Runtime.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/Runtime.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -797,7 +798,7 @@ load0(Reflection.getCallerClass(), filename); } - synchronized void load0(Class fromClass, String filename) { + void load0(Class fromClass, String filename) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(filename); @@ -858,14 +859,14 @@ loadLibrary0(Reflection.getCallerClass(), libname); } - synchronized void loadLibrary0(Class fromClass, String libname) { + void loadLibrary0(Class fromClass, String libname) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(libname); } if (libname.indexOf((int)File.separatorChar) != -1) { throw new UnsatisfiedLinkError( - "Directory separator should not appear in library name: " + libname); + "Directory separator should not appear in library name: " + libname); } ClassLoader.loadLibrary(fromClass, libname, false); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/System.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/System.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/lang/System.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/lang/System.java 2020-01-15 20:05:09.000000000 +0000 @@ -43,6 +43,8 @@ import sun.security.util.SecurityConstants; import sun.reflect.annotation.AnnotationType; +import jdk.internal.util.StaticProperty; + /** * The System class contains several useful class fields * and methods. It cannot be instantiated. @@ -1183,6 +1185,7 @@ lineSeparator = props.getProperty("line.separator"); + StaticProperty.jdkSerialFilter(); // Load StaticProperty to cache the property values sun.misc.Version.init(); FileInputStream fdIn = new FileInputStream(FileDescriptor.in); @@ -1192,6 +1195,8 @@ setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); + ClassLoader.initLibraryPaths(); + // Load the zip library now in order to keep java.util.zip.ZipFile // from trying to use itself to load this library later. loadLibrary("zip"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/net/URL.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/net/URL.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/net/URL.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/net/URL.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,6 +33,7 @@ import java.io.ObjectInputStream.GetField; import java.util.Hashtable; import java.util.StringTokenizer; +import sun.misc.VM; import sun.net.util.IPAddressUtil; import sun.security.util.SecurityConstants; @@ -1423,7 +1424,9 @@ } boolean isBuiltinStreamHandler(URLStreamHandler handler) { - return isBuiltinStreamHandler(handler.getClass().getName()); + Class handlerClass = handler.getClass(); + return isBuiltinStreamHandler(handlerClass.getName()) + || VM.isSystemDomainLoader(handlerClass.getClassLoader()); } private boolean isBuiltinStreamHandler(String handlerClassName) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/nio/channels/SelectableChannel.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/nio/channels/SelectableChannel.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/nio/channels/SelectableChannel.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/nio/channels/SelectableChannel.java 2020-01-15 20:05:09.000000000 +0000 @@ -121,7 +121,7 @@ // keySet, may be empty but is never null, typ. a tiny array // boolean isRegistered, protected by key set // regLock, lock object to prevent duplicate registrations - // boolean isBlocking, protected by regLock + // blocking mode, protected by regLock /** * Tells whether or not this channel is currently registered with any diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,14 @@ package java.nio.channels.spi; import java.io.IOException; -import java.nio.channels.*; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.IllegalSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; /** @@ -67,8 +74,8 @@ // Lock for registration and configureBlocking operations private final Object regLock = new Object(); - // Blocking mode, protected by regLock - boolean blocking = true; + // True when non-blocking, need regLock to change; + private volatile boolean nonBlocking; /** * Initializes a new instance of this class. @@ -197,7 +204,7 @@ throw new ClosedChannelException(); if ((ops & ~validOps()) != 0) throw new IllegalArgumentException(); - if (blocking) + if (isBlocking()) throw new IllegalBlockingModeException(); SelectionKey k = findKey(sel); if (k != null) { @@ -264,9 +271,7 @@ // -- Blocking -- public final boolean isBlocking() { - synchronized (regLock) { - return blocking; - } + return !nonBlocking; } public final Object blockingLock() { @@ -287,12 +292,13 @@ synchronized (regLock) { if (!isOpen()) throw new ClosedChannelException(); - if (blocking == block) - return this; - if (block && haveValidKeys()) - throw new IllegalBlockingModeException(); - implConfigureBlocking(block); - blocking = block; + boolean blocking = !nonBlocking; + if (block != blocking) { + if (block && haveValidKeys()) + throw new IllegalBlockingModeException(); + implConfigureBlocking(block); + nonBlocking = !block; + } } return this; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.rmi.Remote; +import java.rmi.RemoteException; import java.rmi.UnexpectedException; import java.rmi.activation.Activatable; import java.security.PrivilegedAction; @@ -224,6 +225,13 @@ throw new IllegalArgumentException( "proxy not Remote instance"); } + + // Verify that the method is declared on an interface that extends Remote + Class decl = method.getDeclaringClass(); + if (!Remote.class.isAssignableFrom(decl)) { + throw new RemoteException("Method is not Remote: " + decl + "::" + method); + } + return ref.invoke((Remote) proxy, method, args, getMethodHash(method)); } catch (Exception e) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/CertificateRevokedException.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/CertificateRevokedException.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/CertificateRevokedException.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/CertificateRevokedException.java 2020-01-15 20:05:09.000000000 +0000 @@ -239,7 +239,7 @@ for (int i = 0; i < size; i++) { String oid = (String) ois.readObject(); boolean critical = ois.readBoolean(); - byte[] extVal = IOUtils.readNBytes(ois, ois.readInt()); + byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt()); Extension ext = sun.security.x509.Extension.newExtension (new ObjectIdentifier(oid), critical, extVal); extensions.put(oid, ext); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/CRLReason.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/CRLReason.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/CRLReason.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/CRLReason.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ /** * The CRLReason enumeration specifies the reason that a certificate - * is revoked, as defined in - * RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL + * is revoked, as defined in + * RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL * Profile. * * @author Sean Mullan diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/PKIXReason.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/PKIXReason.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/PKIXReason.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/PKIXReason.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ /** * The {@code PKIXReason} enumerates the potential PKIX-specific reasons * that an X.509 certification path may be invalid according to the PKIX - * (RFC 3280) standard. These reasons are in addition to those of the + * (RFC 5280) standard. These reasons are in addition to those of the * {@code CertPathValidatorException.BasicReason} enumeration. * * @since 1.7 diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/TrustAnchor.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/TrustAnchor.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/TrustAnchor.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/TrustAnchor.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,7 @@ * The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they * would appear in the NameConstraints structure defined in - * RFC 3280 + * RFC 5280 * and X.509. The ASN.1 definition of this structure appears below. * *

{@code
@@ -140,7 +140,7 @@
      * 

* The name constraints are specified as a byte array. This byte array * contains the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 3280 + * would appear in the NameConstraints structure defined in RFC 5280 * and X.509. The ASN.1 notation for this structure is supplied in the * documentation for * {@link #TrustAnchor(X509Certificate, byte[]) @@ -179,7 +179,7 @@ *

* The name constraints are specified as a byte array. This byte array * contains the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 3280 + * would appear in the NameConstraints structure defined in RFC 5280 * and X.509. The ASN.1 notation for this structure is supplied in the * documentation for * {@link #TrustAnchor(X509Certificate, byte[]) @@ -294,7 +294,7 @@ *

* The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 3280 + * would appear in the NameConstraints structure defined in RFC 5280 * and X.509. The ASN.1 notation for this structure is supplied in the * documentation for * {@link #TrustAnchor(X509Certificate, byte[]) diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509Certificate.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509Certificate.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509Certificate.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509Certificate.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * CA such as a "root" CA. *

* More information can be found in - * RFC 3280: Internet X.509 + * RFC 5280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile. *

* The ASN.1 definition of {@code tbsCertificate} is: @@ -408,7 +408,7 @@ * Gets the {@code issuerUniqueID} value from the certificate. * The issuer unique identifier is present in the certificate * to handle the possibility of reuse of issuer names over time. - * RFC 3280 recommends that names not be reused and that + * RFC 5280 recommends that names not be reused and that * conforming certificates not make use of unique identifiers. * Applications conforming to that profile should be capable of * parsing unique identifiers and making comparisons. @@ -459,7 +459,7 @@ * encipherOnly (7), * decipherOnly (8) } *

- * RFC 3280 recommends that when used, this be marked + * RFC 5280 recommends that when used, this be marked * as a critical extension. * * @return the KeyUsage extension of this certificate, represented as @@ -572,7 +572,7 @@ * RFC 822, DNS, and URI * names are returned as {@code String}s, * using the well-established string formats for those types (subject to - * the restrictions included in RFC 3280). IPv4 address names are + * the restrictions included in RFC 5280). IPv4 address names are * returned using dotted quad notation. IPv6 address names are returned * in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values * representing the eight 16-bit pieces of the address. OID names are diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CertSelector.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CertSelector.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CertSelector.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CertSelector.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * number. Other unique combinations include the issuer, subject, * subjectKeyIdentifier and/or the subjectPublicKey criteria. *

- * Please refer to RFC 3280: + * Please refer to RFC 5280: * Internet X.509 Public Key Infrastructure Certificate and CRL Profile for * definitions of the X.509 certificate extensions mentioned below. *

@@ -728,7 +728,7 @@ * The name is provided in string format. * RFC 822, DNS, and URI * names use the well-established string formats for those types (subject to - * the restrictions included in RFC 3280). IPv4 address names are + * the restrictions included in RFC 5280). IPv4 address names are * supplied using dotted quad notation. OID address names are represented * as a series of nonnegative integers separated by periods. And * directory names (distinguished names) are supplied in RFC 2253 format. @@ -746,7 +746,7 @@ * String form of some distinguished names. * * @param type the name type (0-8, as specified in - * RFC 3280, section 4.2.1.7) + * RFC 5280, section 4.2.1.6) * @param name the name in string form (not {@code null}) * @throws IOException if a parsing error occurs */ @@ -770,7 +770,7 @@ *

* The name is provided as a byte array. This byte array should contain * the DER encoded name, as it would appear in the GeneralName structure - * defined in RFC 3280 and X.509. The encoded byte array should only contain + * defined in RFC 5280 and X.509. The encoded byte array should only contain * the encoded value of the name, and should not include the tag associated * with the name in the GeneralName structure. The ASN.1 definition of this * structure appears below. @@ -806,7 +806,7 @@ * must contain the specified subjectAlternativeName. * * @param type the name type (0-8, as specified in - * RFC 3280, section 4.2.1.7) + * RFC 5280, section 4.2.1.6) * @param name the name in string or byte array form * @throws IOException if a parsing error occurs */ @@ -995,7 +995,7 @@ *

* The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 3280 + * would appear in the NameConstraints structure defined in RFC 5280 * and X.509. The ASN.1 definition of this structure appears below. * *

{@code
@@ -1197,7 +1197,7 @@
      * 

* The name is provided in string format. RFC 822, DNS, and URI names * use the well-established string formats for those types (subject to - * the restrictions included in RFC 3280). IPv4 address names are + * the restrictions included in RFC 5280). IPv4 address names are * supplied using dotted quad notation. OID address names are represented * as a series of nonnegative integers separated by periods. And * directory names (distinguished names) are supplied in RFC 2253 format. @@ -1214,7 +1214,7 @@ * String form of some distinguished names. * * @param type the name type (0-8, as specified in - * RFC 3280, section 4.2.1.7) + * RFC 5280, section 4.2.1.6) * @param name the name in string form * @throws IOException if a parsing error occurs */ @@ -1234,7 +1234,7 @@ *

* The name is provided as a byte array. This byte array should contain * the DER encoded name, as it would appear in the GeneralName structure - * defined in RFC 3280 and X.509. The ASN.1 definition of this structure + * defined in RFC 5280 and X.509. The ASN.1 definition of this structure * appears in the documentation for * {@link #addSubjectAlternativeName(int type, byte [] name) * addSubjectAlternativeName(int type, byte [] name)}. @@ -1243,7 +1243,7 @@ * subsequent modifications. * * @param type the name type (0-8, as specified in - * RFC 3280, section 4.2.1.7) + * RFC 5280, section 4.2.1.6) * @param name a byte array containing the name in ASN.1 DER encoded form * @throws IOException if a parsing error occurs */ @@ -1258,7 +1258,7 @@ * the specified pathToName. * * @param type the name type (0-8, as specified in - * RFC 3280, section 4.2.1.7) + * RFC 5280, section 4.2.1.6) * @param name the name in string or byte array form * @throws IOException if an encoding error occurs (incorrect form for DN) */ @@ -1715,7 +1715,7 @@ *

* The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 3280 + * would appear in the NameConstraints structure defined in RFC 5280 * and X.509. The ASN.1 notation for this structure is supplied in the * documentation for * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}. @@ -2115,8 +2115,11 @@ if (certSubjectKeyID == null || !Arrays.equals(subjectKeyID, certSubjectKeyID)) { if (debug != null) { - debug.println("X509CertSelector.match: " - + "subject key IDs don't match"); + debug.println("X509CertSelector.match: subject key IDs " + + "don't match\nX509CertSelector.match: subjectKeyID: " + + Arrays.toString(subjectKeyID) + + "\nX509CertSelector.match: certSubjectKeyID: " + + Arrays.toString(certSubjectKeyID)); } return false; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRL.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRL.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRL.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRL.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * 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,7 +69,7 @@ *

*

* More information can be found in - * RFC 3280: Internet X.509 + * RFC 5280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile. *

* The ASN.1 definition of {@code tbsCertList} is: diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRLSelector.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRLSelector.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRLSelector.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/cert/X509CRLSelector.java 2020-01-15 20:05:09.000000000 +0000 @@ -52,7 +52,7 @@ * {@link CertStore#getCRLs CertStore.getCRLs} or some similar * method. *

- * Please refer to RFC 3280: + * Please refer to RFC 5280: * Internet X.509 Public Key Infrastructure Certificate and CRL Profile * for definitions of the X.509 CRL fields and extensions mentioned below. *

diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/CodeSource.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/CodeSource.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/CodeSource.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/CodeSource.java 2020-01-15 20:05:09.000000000 +0000 @@ -570,7 +570,7 @@ cfs.put(certType, cf); } // parse the certificate - byte[] encoded = IOUtils.readNBytes(ois, ois.readInt()); + byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt()); ByteArrayInputStream bais = new ByteArrayInputStream(encoded); try { certList.add(cf.generateCertificate(bais)); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/Key.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/Key.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/Key.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/Key.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * * * For more information, see - * RFC 3280: + * RFC 5280: * Internet X.509 Public Key Infrastructure Certificate and CRL Profile. * *

  • A Format diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/UnresolvedPermission.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/UnresolvedPermission.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/security/UnresolvedPermission.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/security/UnresolvedPermission.java 2020-01-15 20:05:09.000000000 +0000 @@ -590,7 +590,7 @@ cfs.put(certType, cf); } // parse the certificate - byte[] encoded = IOUtils.readNBytes(ois, ois.readInt()); + byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt()); ByteArrayInputStream bais = new ByteArrayInputStream(encoded); try { certList.add(cf.generateCertificate(bais)); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/util/Formattable.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/util/Formattable.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/util/Formattable.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/util/Formattable.java 2020-01-15 20:05:09.000000000 +0000 @@ -36,14 +36,14 @@ * For example, the following class prints out different representations of a * stock's name depending on the flags and length constraints: * - * {@code + *
     {@code
      *   import java.nio.CharBuffer;
      *   import java.util.Formatter;
      *   import java.util.Formattable;
      *   import java.util.Locale;
      *   import static java.util.FormattableFlags.*;
      *
    - *  ...
    + *   ...
      *
      *   public class StockName implements Formattable {
      *       private String symbol, companyName, frenchCompanyName;
    @@ -89,12 +89,12 @@
      *           return String.format("%s - %s", symbol, companyName);
      *       }
      *   }
    - * }
    + * }
    * *

    When used in conjunction with the {@link java.util.Formatter}, the above * class produces the following output for various format strings. * - * {@code + *

     {@code
      *   Formatter fmt = new Formatter();
      *   StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
      *                                "Fruit Titanesque, Inc.");
    @@ -104,7 +104,7 @@
      *   fmt.format("%-10.8s", sn);              //   -> "HUGE      "
      *   fmt.format("%.12s", sn);                //   -> "Huge Fruit,*"
      *   fmt.format(Locale.FRANCE, "%25s", sn);  //   -> "   Fruit Titanesque, Inc."
    - * }
    + * }
    * *

    Formattables are not necessarily safe for multithreaded access. Thread * safety is optional and may be enforced by classes that extend and implement diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/util/jar/JarFile.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/util/jar/JarFile.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/java/util/jar/JarFile.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/java/util/jar/JarFile.java 2020-01-15 20:05:09.000000000 +0000 @@ -422,7 +422,12 @@ */ private byte[] getBytes(ZipEntry ze) throws IOException { try (InputStream is = super.getInputStream(ze)) { - return IOUtils.readFully(is, (int)ze.getSize(), true); + int len = (int)ze.getSize(); + byte[] b = IOUtils.readAllBytes(is); + if (len != -1 && b.length != len) + throw new EOFException("Expected:" + len + ", read:" + b.length); + + return b; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,6 +33,22 @@ KeyTab ktab) { return ktab.takeSnapshot(); } + + public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t) { + return t.clientAlias; + } + + public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a) { + t.clientAlias = a; + } + + public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t) { + return t.serverAlias; + } + + public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) { + t.serverAlias = a; + } public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) { return t.proxy; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,6 +80,11 @@ public static final int KRB_NT_UID = 5; + /** + * Enterprise name (alias) + */ + static final int KRB_NT_ENTERPRISE = 10; + private transient String fullName; private transient String realm; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java 2020-01-15 20:05:09.000000000 +0000 @@ -194,6 +194,10 @@ private InetAddress[] clientAddresses; + transient KerberosPrincipal clientAlias = null; + + transient KerberosPrincipal serverAlias = null; + /** * Evidence ticket if proxy_impersonator. This field can be accessed * by KerberosSecrets. It's serialized. @@ -308,11 +312,7 @@ } else this.flags = new boolean[NUM_FLAGS]; - if (this.flags[RENEWABLE_TICKET_FLAG]) { - if (renewTill == null) - throw new IllegalArgumentException("The renewable period " - + "end time cannot be null for renewable tickets."); - + if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) { this.renewTill = new Date(renewTill.getTime()); } @@ -553,6 +553,11 @@ if (!isRenewable()) throw new RefreshFailedException("This ticket is not renewable"); + if (getRenewTill() == null) { + // Renewable ticket without renew-till. Illegal and ignored. + return; + } + if (System.currentTimeMillis() > getRenewTill().getTime()) throw new RefreshFailedException("This ticket is past " + "its last renewal time."); @@ -562,7 +567,11 @@ try { krb5Creds = new sun.security.krb5.Credentials(asn1Encoding, client.toString(), + (clientAlias != null ? + clientAlias.getName() : null), server.toString(), + (serverAlias != null ? + serverAlias.getName() : null), sessionKey.getEncoded(), sessionKey.getKeyType(), flags, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/package-info.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/package-info.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/package-info.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/package-info.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * 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,15 +31,15 @@ *

    Package Specification

    * * diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/X500Principal.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/X500Principal.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/X500Principal.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/security/auth/x500/X500Principal.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * 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,13 +41,13 @@ * of the distinguished name, or by using the ASN.1 DER encoded byte * representation of the distinguished name. The current specification * for the string representation of a distinguished name is defined in - * RFC 2253: Lightweight + * RFC 2253: Lightweight * Directory Access Protocol (v3): UTF-8 String Representation of * Distinguished Names. This class, however, accepts string formats from - * both RFC 2253 and RFC 1779: + * both RFC 2253 and RFC 1779: * A String Representation of Distinguished Names, and also recognizes * attribute type keywords whose OIDs (Object Identifiers) are defined in - * RFC 3280: Internet X.509 + * RFC 5280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile. * *

    The string representation for this {@code X500Principal} @@ -108,7 +108,7 @@ * (and listed in {@link #getName(String format) getName(String format)}), * as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS, * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object - * Identifiers (OIDs) are defined in RFC 3280 and its successor. + * Identifiers (OIDs) are defined in RFC 5280. * Any other attribute type must be specified as an OID. * *

    This implementation enforces a more restrictive OID syntax than @@ -456,7 +456,7 @@ * (obtained via the {@code getName(X500Principal.CANONICAL)} method) * of this object and o are equal. * - *

    This implementation is compliant with the requirements of RFC 3280. + *

    This implementation is compliant with the requirements of RFC 5280. * * @param o Object to be compared for equality with this * {@code X500Principal} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/swing/ToolTipManager.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/swing/ToolTipManager.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/javax/swing/ToolTipManager.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/javax/swing/ToolTipManager.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ import java.awt.event.*; import java.awt.*; +import javax.swing.event.MenuKeyEvent; +import javax.swing.event.MenuKeyListener; /** * Manages all the ToolTips in the system. @@ -409,8 +411,14 @@ component.addMouseListener(this); component.removeMouseMotionListener(moveBeforeEnterListener); component.addMouseMotionListener(moveBeforeEnterListener); - component.removeKeyListener(accessibilityKeyListener); - component.addKeyListener(accessibilityKeyListener); + // use MenuKeyListener for menu items/elements + if (component instanceof JMenuItem) { + ((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener); + ((JMenuItem) component).addMenuKeyListener((MenuKeyListener) accessibilityKeyListener); + } else { + component.removeKeyListener(accessibilityKeyListener); + component.addKeyListener(accessibilityKeyListener); + } } /** @@ -421,7 +429,11 @@ public void unregisterComponent(JComponent component) { component.removeMouseListener(this); component.removeMouseMotionListener(moveBeforeEnterListener); - component.removeKeyListener(accessibilityKeyListener); + if (component instanceof JMenuItem) { + ((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener); + } else { + component.removeKeyListener(accessibilityKeyListener); + } } // implements java.awt.event.MouseListener @@ -841,7 +853,7 @@ * Post Tip: Ctrl+F1 * Unpost Tip: Esc and Ctrl+F1 */ - private class AccessibilityKeyListener extends KeyAdapter { + private class AccessibilityKeyListener extends KeyAdapter implements MenuKeyListener { public void keyPressed(KeyEvent e) { if (!e.isConsumed()) { JComponent source = (JComponent) e.getComponent(); @@ -858,5 +870,32 @@ } } } + + @Override + public void menuKeyTyped(MenuKeyEvent e) {} + + @Override + public void menuKeyPressed(MenuKeyEvent e) { + if (postTip.equals(KeyStroke.getKeyStrokeForEvent(e))) { + // get element for the event + MenuElement path[] = e.getPath(); + MenuElement element = path[path.length - 1]; + + // retrieve currently highlighted element + MenuSelectionManager msm = e.getMenuSelectionManager(); + MenuElement selectedPath[] = msm.getSelectedPath(); + MenuElement selectedElement = selectedPath[selectedPath.length - 1]; + + if (element.equals(selectedElement)) { + // show/hide tooltip message + JComponent source = (JComponent) element.getComponent(); + ToolTipManager.this.show(source); + e.consume(); + } + } + } + + @Override + public void menuKeyReleased(MenuKeyEvent e) {} } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/jdk/internal/util/StaticProperty.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/jdk/internal/util/StaticProperty.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/jdk/internal/util/StaticProperty.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/jdk/internal/util/StaticProperty.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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.internal.util; + +/** + * System Property access for internal use only. + * Read-only access to System property values initialized during Phase 1 + * are cached. Setting, clearing, or modifying the value using + * {@link System#setProperty) or {@link System#getProperties()} is ignored. + * {@link SecurityManager#checkPropertyAccess} is NOT checked + * in these access methods. The caller of these methods should take care to ensure + * that the returned property is not made accessible to untrusted code. + */ +public final class StaticProperty { + + // The class static initialization is triggered to initialize these final + // fields during init Phase 1 and before a security manager is set. + private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter"); + + private StaticProperty() {} + + /** + * + * Return the {@code jdk.serialFilter} system property. + * + * {@link SecurityManager#checkPropertyAccess} is NOT checked + * in this method. The caller of this method should take care to ensure + * that the returned property is not made accessible to untrusted code. + * + * @return the {@code user.name} system property + */ + public static String jdkSerialFilter() { + return JDK_SERIAL_FILTER; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/applet/AppletClassLoader.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/applet/AppletClassLoader.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/applet/AppletClassLoader.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/applet/AppletClassLoader.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,6 +33,7 @@ import java.net.MalformedURLException; import java.net.InetAddress; import java.net.UnknownHostException; +import java.io.EOFException; import java.io.File; import java.io.FilePermission; import java.io.IOException; @@ -333,7 +334,9 @@ byte[] b; try { - b = IOUtils.readFully(in, len, true); + b = IOUtils.readAllBytes(in); + if (len != -1 && b.length != len) + throw new EOFException("Expected:" + len + ", read:" + b.length); } finally { in.close(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java 2020-01-15 20:05:09.000000000 +0000 @@ -27,6 +27,7 @@ import java.awt.AlphaComposite; import java.awt.Composite; +import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.Transparency; @@ -598,16 +599,16 @@ * (referenced by the pData parameter). This method is invoked from * the native Dispose() method from the Disposer thread when the * Java-level OGLSurfaceData object is about to go away. Note that we - * also pass a reference to the native GLX/WGLGraphicsConfigInfo - * (pConfigInfo) for the purposes of making a context current. + * also pass a reference to the OGLGraphicsConfig + * for the purposes of making a context current. */ - static void dispose(long pData, long pConfigInfo) { + static void dispose(long pData, OGLGraphicsConfig gc) { OGLRenderQueue rq = OGLRenderQueue.getInstance(); rq.lock(); try { // make sure we have a current context before // disposing the native resources (e.g. texture object) - OGLContext.setScratchSurface(pConfigInfo); + OGLContext.setScratchSurface(gc); RenderBuffer buf = rq.getBuffer(); rq.ensureCapacityAndAlignment(12, 4); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/IOUtils.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/IOUtils.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/IOUtils.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/IOUtils.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,67 +32,282 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; + +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.Objects; public class IOUtils { + private static final int DEFAULT_BUFFER_SIZE = 8192; + /** - * Read up to {@code length} of bytes from {@code in} - * until EOF is detected. + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + /** + * Read exactly {@code length} of bytes from {@code in}. + * + *

    Note that this method is safe to be called with unknown large + * {@code length} argument. The memory used is proportional to the + * actual bytes available. An exception is thrown if there are not + * enough bytes in the stream. + * * @param is input stream, must not be null - * @param length number of bytes to read, -1 or Integer.MAX_VALUE means - * read as much as possible - * @param readAll if true, an EOFException will be thrown if not enough - * bytes are read. Ignored when length is -1 or Integer.MAX_VALUE + * @param length number of bytes to read * @return bytes read - * @throws IOException Any IO error or a premature EOF is detected + * @throws EOFException if there are not enough bytes in the stream + * @throws IOException if an I/O error occurs or {@code length} is negative + * @throws OutOfMemoryError if an array of the required size cannot be + * allocated. */ - public static byte[] readFully(InputStream is, int length, boolean readAll) + public static byte[] readExactlyNBytes(InputStream is, int length) throws IOException { - byte[] output = {}; - if (length == -1) length = Integer.MAX_VALUE; - int pos = 0; - while (pos < length) { - int bytesToRead; - if (pos >= output.length) { // Only expand when there's no room - bytesToRead = Math.min(length - pos, output.length + 1024); - if (output.length < pos + bytesToRead) { - output = Arrays.copyOf(output, pos + bytesToRead); - } - } else { - bytesToRead = output.length - pos; + if (length < 0) { + throw new IOException("length cannot be negative: " + length); + } + byte[] data = readNBytes(is, length); + if (data.length < length) { + throw new EOFException(); + } + return data; + } + + /** + * Reads all remaining bytes from the input stream. This method blocks until + * all remaining bytes have been read and end of stream is detected, or an + * exception is thrown. This method does not close the input stream. + * + *

    When this stream reaches end of stream, further invocations of this + * method will return an empty byte array. + * + *

    Note that this method is intended for simple cases where it is + * convenient to read all bytes into a byte array. It is not intended for + * reading input streams with large amounts of data. + * + *

    The behavior for the case where the input stream is asynchronously + * closed, or the thread interrupted during the read, is highly input + * stream specific, and therefore not specified. + * + *

    If an I/O error occurs reading from the input stream, then it may do + * so after some, but not all, bytes have been read. Consequently the input + * stream may not be at end of stream and may be in an inconsistent state. + * It is strongly recommended that the stream be promptly closed if an I/O + * error occurs. + * + * @implSpec + * This method invokes {@link #readNBytes(int)} with a length of + * {@link Integer#MAX_VALUE}. + * + * @param is input stream, must not be null + * @return a byte array containing the bytes read from this input stream + * @throws IOException if an I/O error occurs + * @throws OutOfMemoryError if an array of the required size cannot be + * allocated. + * + * @since 1.9 + */ + public static byte[] readAllBytes(InputStream is) throws IOException { + return readNBytes(is, Integer.MAX_VALUE); + } + + /** + * Reads up to a specified number of bytes from the input stream. This + * method blocks until the requested number of bytes have been read, end + * of stream is detected, or an exception is thrown. This method does not + * close the input stream. + * + *

    The length of the returned array equals the number of bytes read + * from the stream. If {@code len} is zero, then no bytes are read and + * an empty byte array is returned. Otherwise, up to {@code len} bytes + * are read from the stream. Fewer than {@code len} bytes may be read if + * end of stream is encountered. + * + *

    When this stream reaches end of stream, further invocations of this + * method will return an empty byte array. + * + *

    Note that this method is intended for simple cases where it is + * convenient to read the specified number of bytes into a byte array. The + * total amount of memory allocated by this method is proportional to the + * number of bytes read from the stream which is bounded by {@code len}. + * Therefore, the method may be safely called with very large values of + * {@code len} provided sufficient memory is available. + * + *

    The behavior for the case where the input stream is asynchronously + * closed, or the thread interrupted during the read, is highly input + * stream specific, and therefore not specified. + * + *

    If an I/O error occurs reading from the input stream, then it may do + * so after some, but not all, bytes have been read. Consequently the input + * stream may not be at end of stream and may be in an inconsistent state. + * It is strongly recommended that the stream be promptly closed if an I/O + * error occurs. + * + * @implNote + * The number of bytes allocated to read data from this stream and return + * the result is bounded by {@code 2*(long)len}, inclusive. + * + * @param is input stream, must not be null + * @param len the maximum number of bytes to read + * @return a byte array containing the bytes read from this input stream + * @throws IllegalArgumentException if {@code length} is negative + * @throws IOException if an I/O error occurs + * @throws OutOfMemoryError if an array of the required size cannot be + * allocated. + * + * @since 11 + */ + public static byte[] readNBytes(InputStream is, int len) throws IOException { + if (len < 0) { + throw new IllegalArgumentException("len < 0"); + } + + List bufs = null; + byte[] result = null; + int total = 0; + int remaining = len; + int n; + do { + byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)]; + int nread = 0; + + // read to EOF which may read more or less than buffer size + while ((n = is.read(buf, nread, + Math.min(buf.length - nread, remaining))) > 0) { + nread += n; + remaining -= n; } - int cc = is.read(output, pos, bytesToRead); - if (cc < 0) { - if (readAll && length != Integer.MAX_VALUE) { - throw new EOFException("Detect premature EOF"); + + if (nread > 0) { + if (MAX_BUFFER_SIZE - total < nread) { + throw new OutOfMemoryError("Required array size too large"); + } + total += nread; + if (result == null) { + result = buf; } else { - if (output.length != pos) { - output = Arrays.copyOf(output, pos); + if (bufs == null) { + bufs = new ArrayList<>(); + bufs.add(result); } - break; + bufs.add(buf); } } - pos += cc; + // if the last call to read returned -1 or the number of bytes + // requested have been read then break + } while (n >= 0 && remaining > 0); + + if (bufs == null) { + if (result == null) { + return new byte[0]; + } + return result.length == total ? + result : Arrays.copyOf(result, total); + } + + result = new byte[total]; + int offset = 0; + remaining = total; + for (byte[] b : bufs) { + int count = Math.min(b.length, remaining); + System.arraycopy(b, 0, result, offset, count); + offset += count; + remaining -= count; + } + + return result; + } + + /** + * Reads the requested number of bytes from the input stream into the given + * byte array. This method blocks until {@code len} bytes of input data have + * been read, end of stream is detected, or an exception is thrown. The + * number of bytes actually read, possibly zero, is returned. This method + * does not close the input stream. + * + *

    In the case where end of stream is reached before {@code len} bytes + * have been read, then the actual number of bytes read will be returned. + * When this stream reaches end of stream, further invocations of this + * method will return zero. + * + *

    If {@code len} is zero, then no bytes are read and {@code 0} is + * returned; otherwise, there is an attempt to read up to {@code len} bytes. + * + *

    The first byte read is stored into element {@code b[off]}, the next + * one in to {@code b[off+1]}, and so on. The number of bytes read is, at + * most, equal to {@code len}. Let k be the number of bytes actually + * read; these bytes will be stored in elements {@code b[off]} through + * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k + * {@code ]} through {@code b[off+len-1]} unaffected. + * + *

    The behavior for the case where the input stream is asynchronously + * closed, or the thread interrupted during the read, is highly input + * stream specific, and therefore not specified. + * + *

    If an I/O error occurs reading from the input stream, then it may do + * so after some, but not all, bytes of {@code b} have been updated with + * data from the input stream. Consequently the input stream and {@code b} + * may be in an inconsistent state. It is strongly recommended that the + * stream be promptly closed if an I/O error occurs. + * + * @param is input stream, must not be null + * @param b the byte array into which the data is read + * @param off the start offset in {@code b} at which the data is written + * @param len the maximum number of bytes to read + * @return the actual number of bytes read into the buffer + * @throws IOException if an I/O error occurs + * @throws NullPointerException if {@code b} is {@code null} + * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} + * is negative, or {@code len} is greater than {@code b.length - off} + * + * @since 1.9 + */ + public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException { + Objects.requireNonNull(b); + if (off < 0 || len < 0 || len > b.length - off) + throw new IndexOutOfBoundsException(); + int n = 0; + while (n < len) { + int count = is.read(b, off + n, len - n); + if (count < 0) + break; + n += count; } - return output; + return n; } /** - * Read {@code length} of bytes from {@code in}. An exception is - * thrown if there are not enough bytes in the stream. + * Compatibility wrapper for third party users of + * {@code sun.misc.IOUtils.readFully} following its + * removal in JDK-8231139. + * + * Read up to {@code length} of bytes from {@code in} + * until EOF is detected. * * @param is input stream, must not be null - * @param length number of bytes to read, must not be negative + * @param length number of bytes to read + * @param readAll if true, an EOFException will be thrown if not enough + * bytes are read. * @return bytes read - * @throws IOException if any IO error or a premature EOF is detected, or - * if {@code length} is negative since this length is usually also - * read from {@code is}. + * @throws EOFException if there are not enough bytes in the stream + * @throws IOException if an I/O error occurs or {@code length} is negative + * @throws OutOfMemoryError if an array of the required size cannot be + * allocated. */ - public static byte[] readNBytes(InputStream is, int length) throws IOException { + public static byte[] readFully(InputStream is, int length, boolean readAll) + throws IOException { if (length < 0) { throw new IOException("length cannot be negative: " + length); } - return readFully(is, length, true); + if (readAll) { + return readExactlyNBytes(is, length); + } else { + return readNBytes(is, length); + } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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.misc; + +import java.io.IOException; +import java.io.ObjectInputStream; + +/** + * Interface to specify methods for accessing {@code ObjectInputStream}. + */ +@FunctionalInterface +public interface JavaObjectInputStreamReadString { + String readString(ObjectInputStream ois) throws IOException; +} + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/ObjectInputFilter.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/ObjectInputFilter.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/ObjectInputFilter.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/ObjectInputFilter.java 2020-01-15 20:05:09.000000000 +0000 @@ -37,6 +37,8 @@ import java.util.function.Function; import sun.util.logging.PlatformLogger; +import jdk.internal.util.StaticProperty; + /** * Filter classes, array lengths, and graph metrics during deserialization. * If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)} @@ -247,7 +249,7 @@ static { configuredFilter = AccessController .doPrivileged((PrivilegedAction) () -> { - String props = System.getProperty(SERIAL_FILTER_PROPNAME); + String props = StaticProperty.jdkSerialFilter(); if (props == null) { props = Security.getProperty(SERIAL_FILTER_PROPNAME); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/SharedSecrets.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/SharedSecrets.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/SharedSecrets.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/SharedSecrets.java 2020-01-15 20:05:09.000000000 +0000 @@ -59,6 +59,7 @@ private static JavaAWTAccess javaAWTAccess; private static JavaOISAccess javaOISAccess; private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; + private static JavaObjectInputStreamReadString javaObjectInputStreamReadString; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; public static JavaUtilJarAccess javaUtilJarAccess() { @@ -202,8 +203,18 @@ return javaAWTAccess; } + public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() { + if (javaObjectInputStreamReadString == null) { + unsafe.ensureClassInitialized(ObjectInputStream.class); + } + return javaObjectInputStreamReadString; + } + + public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) { + javaObjectInputStreamReadString = access; + } - public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() { + public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() { if (javaObjectInputStreamAccess == null) { unsafe.ensureClassInitialized(ObjectInputStream.class); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/URLClassPath.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/URLClassPath.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/misc/URLClassPath.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/misc/URLClassPath.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1229,10 +1229,15 @@ int i = 0; while (st.hasMoreTokens()) { String path = st.nextToken(); - URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path); + URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path); if (url != null) { urls[i] = url; i++; + } else { + if (DEBUG_CP_URL_CHECK) { + System.err.println("Class-Path entry: \"" + path + + "\" ignored in JAR file " + base); + } } } if (i == 0) { @@ -1244,36 +1249,74 @@ return urls; } - /* - * Return a URL for the given path resolved against the base URL, or - * null if the resulting URL is invalid. + static URL tryResolve(URL base, String input) throws MalformedURLException { + if ("file".equalsIgnoreCase(base.getProtocol())) { + return tryResolveFile(base, input); + } else { + return tryResolveNonFile(base, input); + } + } + + /** + * Attempt to return a file URL by resolving input against a base file + * URL. The input is an absolute or relative file URL that encodes a + * file path. + * + * @apiNote Nonsensical input such as a Windows file path with a drive + * letter cannot be disambiguated from an absolute URL so will be rejected + * (by returning null) by this method. + * + * @return the resolved URL or null if the input is an absolute URL with + * a scheme other than file (ignoring case) + * @throws MalformedURLException */ - static URL safeResolve(URL base, String path) { - String child = path.replace(File.separatorChar, '/'); - try { - if (!URI.create(child).isAbsolute()) { - URL url = new URL(base, child); - if (base.getProtocol().equalsIgnoreCase("file")) { - return url; - } else { - String bp = base.getPath(); - String urlp = url.getPath(); - int pos = bp.lastIndexOf('/'); - if (pos == -1) { - pos = bp.length() - 1; - } - if (urlp.regionMatches(0, bp, 0, pos + 1) - && urlp.indexOf("..", pos) == -1) { - return url; - } - } + static URL tryResolveFile(URL base, String input) throws MalformedURLException { + int index = input.indexOf(':'); + boolean isFile; + if (index >= 0) { + String scheme = input.substring(0, index); + isFile = "file".equalsIgnoreCase(scheme); + } else { + isFile = true; + } + return (isFile) ? new URL(base, input) : null; + } + + /** + * Attempt to return a URL by resolving input against a base URL. Returns + * null if the resolved URL is not contained by the base URL. + * + * @return the resolved URL or null + * @throws MalformedURLException + */ + static URL tryResolveNonFile(URL base, String input) throws MalformedURLException { + String child = input.replace(File.separatorChar, '/'); + if (isRelative(child)) { + URL url = new URL(base, child); + String bp = base.getPath(); + String urlp = url.getPath(); + int pos = bp.lastIndexOf('/'); + if (pos == -1) { + pos = bp.length() - 1; + } + if (urlp.regionMatches(0, bp, 0, pos + 1) + && urlp.indexOf("..", pos) == -1) { + return url; } - } catch (MalformedURLException | IllegalArgumentException e) {} - if (DEBUG_CP_URL_CHECK) { - System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base); } return null; } + + /** + * Returns true if the given input is a relative URI. + */ + static boolean isRelative(String child) { + try { + return !URI.create(child).isAbsolute(); + } catch (IllegalArgumentException e) { + return false; + } + } } /* diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/net/www/MessageHeader.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/net/www/MessageHeader.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/net/www/MessageHeader.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/net/www/MessageHeader.java 2020-01-15 20:05:09.000000000 +0000 @@ -288,14 +288,44 @@ return Collections.unmodifiableMap(m); } + /** Check if a line of message header looks like a request line. + * This method does not perform a full validation but simply + * returns false if the line does not end with 'HTTP/[1-9].[0-9]' + * @param line the line to check. + * @return true if the line might be a request line. + */ + private boolean isRequestline(String line) { + String k = line.trim(); + int i = k.lastIndexOf(' '); + if (i <= 0) return false; + int len = k.length(); + if (len - i < 9) return false; + + char c1 = k.charAt(len-3); + char c2 = k.charAt(len-2); + char c3 = k.charAt(len-1); + if (c1 < '1' || c1 > '9') return false; + if (c2 != '.') return false; + if (c3 < '0' || c3 > '9') return false; + + return (k.substring(i+1, len-3).equalsIgnoreCase("HTTP/")); + } + + /** Prints the key-value pairs represented by this - header. Also prints the RFC required blank line - at the end. Omits pairs with a null key. */ + header. Also prints the RFC required blank line + at the end. Omits pairs with a null key. Omits + colon if key-value pair is the requestline. */ public synchronized void print(PrintStream p) { for (int i = 0; i < nkeys; i++) if (keys[i] != null) { - p.print(keys[i] + - (values[i] != null ? ": "+values[i]: "") + "\r\n"); + StringBuilder sb = new StringBuilder(keys[i]); + if (values[i] != null) { + sb.append(": " + values[i]); + } else if (i != 0 || !isRequestline(keys[i])) { + sb.append(":"); + } + p.print(sb.append("\r\n")); } p.print("\r\n"); p.flush(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramChannelImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramChannelImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -49,9 +49,6 @@ // Our file descriptor private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 private final int fdVal; // The protocol family of the socket @@ -103,7 +100,6 @@ // -- End of fields protected by stateLock - public DatagramChannelImpl(SelectorProvider sp) throws IOException { @@ -138,16 +134,27 @@ throw new UnsupportedOperationException("IPv6 not available"); } } - this.family = family; - this.fd = Net.socket(family, false); - this.fdVal = IOUtil.fdVal(fd); - this.state = ST_UNCONNECTED; + + ResourceManager.beforeUdpCreate(); + try { + this.family = family; + this.fd = Net.socket(family, false); + this.fdVal = IOUtil.fdVal(fd); + this.state = ST_UNCONNECTED; + } catch (IOException ioe) { + ResourceManager.afterUdpClose(); + throw ioe; + } } public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd) throws IOException { super(sp); + + // increment UDP count to match decrement when closing + ResourceManager.beforeUdpCreate(); + this.family = Net.isIPv6Available() ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; this.fd = fd; @@ -742,10 +749,9 @@ localAddress = Net.localAddress(fd); // flush any packets already received. - boolean blocking = false; synchronized (blockingLock()) { + boolean blocking = isBlocking(); try { - blocking = isBlocking(); // remainder of each packet thrown away ByteBuffer tmpBuf = ByteBuffer.allocate(1); if (blocking) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -25,10 +25,22 @@ package sun.nio.ch; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.DatagramSocketImpl; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketOption; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.IllegalBlockingModeException; // Make a datagram-socket channel look like a datagram socket. @@ -178,7 +190,6 @@ dc.configureBlocking(false); try { - int n; SocketAddress sender; if ((sender = dc.receive(bb)) != null) return sender; @@ -188,19 +199,18 @@ throw new ClosedChannelException(); long st = System.currentTimeMillis(); int result = dc.poll(Net.POLLIN, to); - if (result > 0 && - ((result & Net.POLLIN) != 0)) { + if (result > 0 && ((result & Net.POLLIN) != 0)) { if ((sender = dc.receive(bb)) != null) return sender; } to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException(); - } } finally { - if (dc.isOpen()) + try { dc.configureBlocking(true); + } catch (ClosedChannelException e) { } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,20 @@ package sun.nio.ch; -import java.io.*; -import java.net.*; -import java.nio.channels.*; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.NotYetBoundException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; // Make a server-socket channel look like a server socket. @@ -37,7 +48,7 @@ // class. // -public class ServerSocketAdaptor // package-private +class ServerSocketAdaptor // package-private extends ServerSocket { @@ -97,12 +108,16 @@ throw new IllegalBlockingModeException(); try { if (timeout == 0) { + // for compatibility reasons: accept connection if available + // when configured non-blocking SocketChannel sc = ssc.accept(); if (sc == null && !ssc.isBlocking()) throw new IllegalBlockingModeException(); return sc.socket(); } + if (!ssc.isBlocking()) + throw new IllegalBlockingModeException(); ssc.configureBlocking(false); try { SocketChannel sc; @@ -121,10 +136,10 @@ throw new SocketTimeoutException(); } } finally { - if (ssc.isOpen()) + try { ssc.configureBlocking(true); + } catch (ClosedChannelException e) { } } - } catch (Exception x) { Net.translateException(x); assert false; @@ -178,8 +193,7 @@ if (!isBound()) return "ServerSocket[unbound]"; return "ServerSocket[addr=" + getInetAddress() + - // ",port=" + getPort() + - ",localport=" + getLocalPort() + "]"; + ",localport=" + getLocalPort() + "]"; } public void setReceiveBufferSize(int size) throws SocketException { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -48,10 +48,7 @@ // Our file descriptor private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 - private int fdVal; + private final int fdVal; // ID of native thread currently blocked in this channel, for signalling private volatile long thread = 0; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketAdaptor.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketAdaptor.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketAdaptor.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketAdaptor.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,23 @@ package sun.nio.ch; -import java.io.*; -import java.lang.ref.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +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.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImpl; +import java.net.SocketOption; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.SocketChannel; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.*; @@ -47,7 +59,7 @@ // java.net.Socket so as to simplify tracking future changes to that class. // -public class SocketAdaptor +class SocketAdaptor extends Socket { @@ -91,7 +103,6 @@ throw new IllegalBlockingModeException(); try { - if (timeout == 0) { sc.connect(remote); return; @@ -119,8 +130,9 @@ } } } finally { - if (sc.isOpen()) + try { sc.configureBlocking(true); + } catch (ClosedChannelException e) { } } } catch (Exception x) { @@ -188,10 +200,11 @@ synchronized (sc.blockingLock()) { if (!sc.isBlocking()) throw new IllegalBlockingModeException(); + if (timeout == 0) return sc.read(bb); - sc.configureBlocking(false); + sc.configureBlocking(false); try { int n; if ((n = sc.read(bb)) != 0) @@ -211,10 +224,10 @@ throw new SocketTimeoutException(); } } finally { - if (sc.isOpen()) + try { sc.configureBlocking(true); + } catch (ClosedChannelException e) { } } - } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketChannelImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketChannelImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketChannelImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/nio/ch/SocketChannelImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -50,9 +50,6 @@ // Our file descriptor object private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 private final int fdVal; // IDs of native threads doing reads and writes, for signalling diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/reflect/misc/MethodUtil.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/reflect/misc/MethodUtil.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/reflect/misc/MethodUtil.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/reflect/misc/MethodUtil.java 2020-01-15 20:05:09.000000000 +0000 @@ -25,6 +25,7 @@ package sun.reflect.misc; +import java.io.EOFException; import java.security.AllPermission; import java.security.AccessController; import java.security.PermissionCollection; @@ -42,8 +43,8 @@ import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; -import sun.misc.IOUtils; +import sun.misc.IOUtils; class Trampoline { static { @@ -382,15 +383,12 @@ } } int len = uc.getContentLength(); - InputStream in = new BufferedInputStream(uc.getInputStream()); - - byte[] b; - try { - b = IOUtils.readFully(in, len, true); - } finally { - in.close(); + try (InputStream in = new BufferedInputStream(uc.getInputStream())) { + byte[] b = IOUtils.readAllBytes(in); + if (len != -1 && b.length != len) + throw new EOFException("Expected:" + len + ", read:" + b.length); + return b; } - return b; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java 2020-01-15 20:05:09.000000000 +0000 @@ -27,7 +27,9 @@ package sun.rmi.registry; import java.io.IOException; +import java.io.ObjectInputStream; +import sun.misc.SharedSecrets; import sun.rmi.transport.StreamRemoteCall; /** @@ -83,8 +85,9 @@ java.lang.String $param_String_1; java.rmi.Remote $param_Remote_2; try { - java.io.ObjectInput in = call.getInputStream(); - $param_String_1 = (java.lang.String) in.readObject(); + ObjectInputStream in = (ObjectInputStream)call.getInputStream(); + $param_String_1 = + SharedSecrets.getJavaObjectInputStreamReadString().readString(in); $param_Remote_2 = (java.rmi.Remote) in.readObject(); } catch (ClassCastException | IOException | ClassNotFoundException e) { call.discardPendingRefs(); @@ -118,9 +121,10 @@ { java.lang.String $param_String_1; try { - java.io.ObjectInput in = call.getInputStream(); - $param_String_1 = (java.lang.String) in.readObject(); - } catch (ClassCastException | IOException | ClassNotFoundException e) { + ObjectInputStream in = (ObjectInputStream)call.getInputStream(); + $param_String_1 = + SharedSecrets.getJavaObjectInputStreamReadString().readString(in); + } catch (ClassCastException | IOException e) { call.discardPendingRefs(); throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); } finally { @@ -144,8 +148,9 @@ java.lang.String $param_String_1; java.rmi.Remote $param_Remote_2; try { - java.io.ObjectInput in = call.getInputStream(); - $param_String_1 = (java.lang.String) in.readObject(); + ObjectInputStream in = (ObjectInputStream)call.getInputStream(); + $param_String_1 = + SharedSecrets.getJavaObjectInputStreamReadString().readString(in); $param_Remote_2 = (java.rmi.Remote) in.readObject(); } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) { call.discardPendingRefs(); @@ -169,9 +174,10 @@ java.lang.String $param_String_1; try { - java.io.ObjectInput in = call.getInputStream(); - $param_String_1 = (java.lang.String) in.readObject(); - } catch (ClassCastException | IOException | ClassNotFoundException e) { + ObjectInputStream in = (ObjectInputStream)call.getInputStream(); + $param_String_1 = + SharedSecrets.getJavaObjectInputStreamReadString().readString(in); + } catch (ClassCastException | IOException e) { call.discardPendingRefs(); throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); } finally { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/server/UnicastRef.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/server/UnicastRef.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/server/UnicastRef.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/server/UnicastRef.java 2020-01-15 20:05:09.000000000 +0000 @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.ObjectInput; +import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.lang.reflect.Method; import java.rmi.MarshalException; @@ -38,6 +39,8 @@ import java.rmi.server.RemoteObject; import java.rmi.server.RemoteRef; import java.security.AccessController; + +import sun.misc.SharedSecrets; import sun.rmi.runtime.Log; import sun.rmi.transport.Connection; import sun.rmi.transport.LiveRef; @@ -318,6 +321,8 @@ } else { throw new Error("Unrecognized primitive type: " + type); } + } else if (type == String.class && in instanceof ObjectInputStream) { + return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in); } else { return in.readObject(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.lang.reflect.Proxy; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; @@ -553,6 +554,9 @@ host = in.readUTF(); port = in.readInt(); csf = (RMIClientSocketFactory) in.readObject(); + if (Proxy.isProxyClass(csf.getClass())) { + throw new IOException("Invalid SocketFactory"); + } break; default: diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/action/GetPropertyAction.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/action/GetPropertyAction.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/action/GetPropertyAction.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/action/GetPropertyAction.java 2020-01-15 20:05:09.000000000 +0000 @@ -108,4 +108,27 @@ new GetPropertyAction(theProp)); } } + + /** + * Convenience method to get a property without going through doPrivileged + * if no security manager is present. This is unsafe for inclusion in a + * public API but allowable here since this class is now encapsulated. + * + * Note that this method performs a privileged action using caller-provided + * inputs. The caller of this method should take care to ensure that the + * inputs are not tainted and the returned property is not made accessible + * to untrusted code if it contains sensitive information. + * + * @param theProp the name of the system property. + * @param defaultVal the default value. + */ + public static String privilegedGetProperty(String theProp, + String defaultVal) { + if (System.getSecurityManager() == null) { + return System.getProperty(theProp, defaultVal); + } else { + return AccessController.doPrivileged( + new GetPropertyAction(theProp, defaultVal)); + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/CipherHelper.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/CipherHelper.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/CipherHelper.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/CipherHelper.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ import sun.security.krb5.internal.crypto.Aes128; import sun.security.krb5.internal.crypto.Aes256; import sun.security.krb5.internal.crypto.ArcFourHmac; +import sun.security.krb5.internal.crypto.EType; class CipherHelper { @@ -77,10 +78,6 @@ private int sgnAlg, sealAlg; private byte[] keybytes; - // new token format from draft-ietf-krb-wg-gssapi-cfx-07 - // proto is used to determine new GSS token format for "newer" etypes - private int proto = 0; - CipherHelper(EncryptionKey key) throws GSSException { etype = key.getEType(); keybytes = key.getBytes(); @@ -106,7 +103,6 @@ case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: sgnAlg = -1; sealAlg = -1; - proto = 1; break; default: @@ -123,8 +119,10 @@ return sealAlg; } + // new token format from draft-ietf-krb-wg-gssapi-cfx-07 + // proto is used to determine new GSS token format for "newer" etypes int getProto() { - return proto; + return EType.isNewer(etype) ? 1 : 0; } int getEType() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import org.ietf.jgss.*; import java.io.InputStream; import java.io.IOException; + +import sun.security.action.GetPropertyAction; import sun.security.krb5.*; import java.net.InetAddress; import sun.security.krb5.internal.AuthorizationData; @@ -36,6 +38,33 @@ class InitSecContextToken extends InitialToken { + // If non-mutual authentication is requested, there is no AP-REP message. + // The acceptor thus has no chance to send the seq-number field to the + // initiator. In this case, the initiator and acceptor should has an + // agreement to derive acceptor's initial seq-number if the acceptor wishes + // to send messages to the initiator. + + // If this flag is true, it will the same as the initiator's initial + // seq-number (as MIT krb5 and Windows SSPI do). Otherwise, it will be zero + // (as Heimdal does). The default value is true. + private static final boolean ACCEPTOR_USE_INITIATOR_SEQNUM; + + static { + // The ACCEPTOR_USE_INITIATOR_SEQNUM value is determined by the system + // property "sun.security.krb5.acceptor.sequence.number.nonmutual", + // which can be set to "initiator", "zero" or "0". + String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual"; + String s = GetPropertyAction.privilegedGetProperty(propName, "initiator"); + if (s.equals("initiator")) { + ACCEPTOR_USE_INITIATOR_SEQNUM = true; + } else if (s.equals("zero") || s.equals("0")) { + ACCEPTOR_USE_INITIATOR_SEQNUM = false; + } else { + throw new AssertionError("Unrecognized value for " + propName + + ": " + s); + } + } + private KrbApReq apReq = null; /** @@ -79,7 +108,10 @@ context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey()); if (!mutualRequired) - context.resetPeerSequenceNumber(0); + context.resetPeerSequenceNumber( + ACCEPTOR_USE_INITIATOR_SEQNUM + ? apReq.getSeqNumber().intValue() + : 0); } /** @@ -144,10 +176,12 @@ apReqSeqNumber.intValue() : 0); context.resetPeerSequenceNumber(peerSeqNumber); - if (!context.getMutualAuthState()) - // Use the same sequence number as the peer - // (Behaviour exhibited by the Windows SSPI server) - context.resetMySequenceNumber(peerSeqNumber); + if (!context.getMutualAuthState()) { + context.resetMySequenceNumber( + ACCEPTOR_USE_INITIATOR_SEQNUM + ? peerSeqNumber + : 0); + } context.setAuthTime( new KerberosTime(apReq.getCreds().getAuthTime()).toString()); context.setTktFlags(apReq.getCreds().getFlags()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Context.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Context.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Context.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Context.java 2020-01-15 20:05:09.000000000 +0000 @@ -713,14 +713,14 @@ if (subject != null && !subject.isReadOnly()) { /* - * Store the service credentials as - * javax.security.auth.kerberos.KerberosTicket in - * the Subject. We could wait till the context is - * succesfully established; however it is easier - * to do here and there is no harm indoing it here. - */ + * Store the service credentials as + * javax.security.auth.kerberos.KerberosTicket in + * the Subject. We could wait until the context is + * successfully established; however it is easier + * to do it here and there is no harm. + */ final KerberosTicket kt = - Krb5Util.credsToTicket(serviceCreds); + Krb5Util.credsToTicket(serviceCreds); AccessController.doPrivileged ( new java.security.PrivilegedAction() { public Void run() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java 2020-01-15 20:05:09.000000000 +0000 @@ -60,7 +60,9 @@ private Krb5InitCredential(Krb5NameElement name, byte[] asn1Encoding, KerberosPrincipal client, + KerberosPrincipal clientAlias, KerberosPrincipal server, + KerberosPrincipal serverAlias, byte[] sessionKey, int keyType, boolean[] flags, @@ -81,14 +83,21 @@ endTime, renewTill, clientAddresses); - + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetClientAlias(this, clientAlias); + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetServerAlias(this, serverAlias); this.name = name; try { // Cache this for later use by the sun.security.krb5 package. krb5Credentials = new Credentials(asn1Encoding, client.getName(), + (clientAlias != null ? + clientAlias.getName() : null), server.getName(), + (serverAlias != null ? + serverAlias.getName() : null), sessionKey, keyType, flags, @@ -111,7 +120,9 @@ Credentials delegatedCred, byte[] asn1Encoding, KerberosPrincipal client, + KerberosPrincipal clientAlias, KerberosPrincipal server, + KerberosPrincipal serverAlias, byte[] sessionKey, int keyType, boolean[] flags, @@ -132,7 +143,10 @@ endTime, renewTill, clientAddresses); - + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetClientAlias(this, clientAlias); + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetServerAlias(this, serverAlias); this.name = name; // A delegated cred does not have all fields set. So do not try to // creat new Credentials out of the delegatedCred. @@ -154,10 +168,18 @@ Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL); } + KerberosPrincipal clientAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetClientAlias(tgt); + KerberosPrincipal serverAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetServerAlias(tgt); Krb5InitCredential result = new Krb5InitCredential(name, tgt.getEncoded(), tgt.getClient(), + clientAlias, tgt.getServer(), + serverAlias, tgt.getSessionKey().getEncoded(), tgt.getSessionKeyType(), tgt.getFlags(), @@ -183,10 +205,14 @@ */ PrincipalName cPrinc = delegatedCred.getClient(); + PrincipalName cAPrinc = delegatedCred.getClientAlias(); PrincipalName sPrinc = delegatedCred.getServer(); + PrincipalName sAPrinc = delegatedCred.getServerAlias(); KerberosPrincipal client = null; + KerberosPrincipal clientAlias = null; KerberosPrincipal server = null; + KerberosPrincipal serverAlias = null; Krb5NameElement credName = null; @@ -197,6 +223,10 @@ client = new KerberosPrincipal(fullName); } + if (cAPrinc != null) { + clientAlias = new KerberosPrincipal(cAPrinc.getName()); + } + // XXX Compare name to credName if (sPrinc != null) { @@ -205,11 +235,17 @@ KerberosPrincipal.KRB_NT_SRV_INST); } + if (sAPrinc != null) { + serverAlias = new KerberosPrincipal(sAPrinc.getName()); + } + return new Krb5InitCredential(credName, delegatedCred, delegatedCred.getEncoded(), client, + clientAlias, server, + serverAlias, sessionKey.getBytes(), sessionKey.getEType(), delegatedCred.getFlags(), diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Util.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Util.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Util.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/Krb5Util.java 2020-01-15 20:05:09.000000000 +0000 @@ -228,7 +228,7 @@ public static KerberosTicket credsToTicket(Credentials serviceCreds) { EncryptionKey sessionKey = serviceCreds.getSessionKey(); - return new KerberosTicket( + KerberosTicket kt = new KerberosTicket( serviceCreds.getEncoded(), new KerberosPrincipal(serviceCreds.getClient().getName()), new KerberosPrincipal(serviceCreds.getServer().getName(), @@ -241,14 +241,35 @@ serviceCreds.getEndTime(), serviceCreds.getRenewTill(), serviceCreds.getClientAddresses()); + PrincipalName clientAlias = serviceCreds.getClientAlias(); + PrincipalName serverAlias = serviceCreds.getServerAlias(); + if (clientAlias != null) { + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetClientAlias(kt, new KerberosPrincipal( + clientAlias.getName(), clientAlias.getNameType())); + } + if (serverAlias != null) { + KerberosSecrets.getJavaxSecurityAuthKerberosAccess() + .kerberosTicketSetServerAlias(kt, new KerberosPrincipal( + serverAlias.getName(), serverAlias.getNameType())); + } + return kt; }; public static Credentials ticketToCreds(KerberosTicket kerbTicket) throws KrbException, IOException { + KerberosPrincipal clientAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetClientAlias(kerbTicket); + KerberosPrincipal serverAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetServerAlias(kerbTicket); return new Credentials( kerbTicket.getEncoded(), kerbTicket.getClient().getName(), + (clientAlias != null ? clientAlias.getName() : null), kerbTicket.getServer().getName(), + (serverAlias != null ? serverAlias.getName() : null), kerbTicket.getSessionKey().getEncoded(), kerbTicket.getSessionKeyType(), kerbTicket.getFlags(), diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -499,11 +499,11 @@ */ class MessageTokenHeader { - private int tokenId; - private byte[] bytes = new byte[TOKEN_HEADER_SIZE]; + private int tokenId; + private byte[] bytes = new byte[TOKEN_HEADER_SIZE]; - // Writes a new token header - public MessageTokenHeader(int tokenId, boolean conf) throws GSSException { + // Writes a new token header + public MessageTokenHeader(int tokenId, boolean conf) throws GSSException { this.tokenId = tokenId; @@ -609,7 +609,7 @@ prop.setQOP(0); // sequence number - seqNumber = readBigEndian(bytes, 0, 8); + seqNumber = readBigEndian(bytes, 12, 4); } /** diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/SubjectComber.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/SubjectComber.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/SubjectComber.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/jgss/krb5/SubjectComber.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package sun.security.jgss.krb5; +import sun.security.krb5.KerberosSecrets; + import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.kerberos.KerberosKey; import javax.security.auth.Subject; @@ -182,24 +184,45 @@ } } else { + KerberosPrincipal serverAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetServerAlias(ticket); if (serverPrincipal == null || - ticket.getServer().getName().equals(serverPrincipal)) { - + ticket.getServer().getName().equals(serverPrincipal) || + (serverAlias != null && + serverPrincipal.equals( + serverAlias.getName()))) { + KerberosPrincipal clientAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetClientAlias(ticket); if (clientPrincipal == null || clientPrincipal.equals( - ticket.getClient().getName())) { + ticket.getClient().getName()) || + (clientAlias != null && + clientPrincipal.equals( + clientAlias.getName()))) { if (oneOnly) { return ticket; } else { // Record names so that tickets will // all belong to same principals if (clientPrincipal == null) { - clientPrincipal = - ticket.getClient().getName(); + if (clientAlias == null) { + clientPrincipal = + ticket.getClient().getName(); + } else { + clientPrincipal = + clientAlias.getName(); + } } if (serverPrincipal == null) { - serverPrincipal = - ticket.getServer().getName(); + if (serverAlias == null) { + serverPrincipal = + ticket.getServer().getName(); + } else { + serverPrincipal = + serverAlias.getName(); + } } answer.add(credClass.cast(ticket)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Checksum.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Checksum.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Checksum.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Checksum.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,7 @@ // draft-brezak-win2k-krb-rc4-hmac-04.txt public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138; + // default checksum type, -1 if not set static int CKSUMTYPE_DEFAULT; static int SAFECKSUMTYPE_DEFAULT; @@ -83,26 +84,19 @@ try { cfg = Config.getInstance(); temp = cfg.get("libdefaults", "default_checksum"); - if (temp != null) - { - CKSUMTYPE_DEFAULT = Config.getType(temp); - } else { - /* - * If the default checksum is not - * specified in the configuration we - * set it to RSA_MD5. We follow the MIT and - * SEAM implementation. - */ - CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5; - } + if (temp != null) { + CKSUMTYPE_DEFAULT = Config.getType(temp); + } else { + CKSUMTYPE_DEFAULT = -1; + } } catch (Exception exc) { if (DEBUG) { System.out.println("Exception in getting default checksum "+ - "value from the configuration " + - "Setting default checksum to be RSA-MD5"); + "value from the configuration. " + + "No default checksum set."); exc.printStackTrace(); } - CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5; + CKSUMTYPE_DEFAULT = -1; } @@ -112,97 +106,100 @@ { SAFECKSUMTYPE_DEFAULT = Config.getType(temp); } else { - SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES; + SAFECKSUMTYPE_DEFAULT = -1; } } catch (Exception exc) { if (DEBUG) { System.out.println("Exception in getting safe default " + "checksum value " + - "from the configuration Setting " + - "safe default checksum to be RSA-MD5"); + "from the configuration Setting. " + + "No safe default checksum set."); exc.printStackTrace(); } - SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES; + SAFECKSUMTYPE_DEFAULT = -1; } } /** * Constructs a new Checksum using the raw data and type. + * + * This constructor is only used by Authenticator Checksum + * {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum} + * where the checksum type must be 0x8003 + * (see https://tools.ietf.org/html/rfc4121#section-4.1.1) + * and checksum field/value is used to convey service flags, + * channel bindings, and optional delegation information. + * This special type does NOT have a {@link CksumType} and has its + * own calculating and verification rules. It does has the same + * ASN.1 encoding though. + * * @data the byte array of checksum. * @new_cksumType the type of checksum. - * */ - // used in InitialToken public Checksum(byte[] data, int new_cksumType) { cksumType = new_cksumType; checksum = data; } /** - * Constructs a new Checksum by calculating the checksum over the data - * using specified checksum type. - * @new_cksumType the type of checksum. - * @data the data that needs to be performed a checksum calculation on. + * Constructs a new Checksum by calculating over the data using + * the specified checksum type. If the checksum is unkeyed, key + * and usage are ignored. + * + * @param new_cksumType the type of checksum. If set to -1, the + * {@linkplain EType#checksumType() mandatory checksum type} + * for the encryption type of {@code key} will be used + * @param data the data that needs to be performed a checksum calculation on + * @param key the key used by a keyed checksum + * @param usage the usage used by a keyed checksum */ - public Checksum(int new_cksumType, byte[] data) - throws KdcErrException, KrbCryptoException { - - cksumType = new_cksumType; - CksumType cksumEngine = CksumType.getInstance(cksumType); - if (!cksumEngine.isSafe()) { - checksum = cksumEngine.calculateChecksum(data, data.length); + public Checksum(int new_cksumType, byte[] data, + EncryptionKey key, int usage) + throws KdcErrException, KrbApErrException, KrbCryptoException { + if (new_cksumType == -1) { + cksumType = EType.getInstance(key.getEType()).checksumType(); } else { - throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM); + cksumType = new_cksumType; } + checksum = CksumType.getInstance(cksumType).calculateChecksum( + data, data.length, key.getBytes(), usage); } /** - * Constructs a new Checksum by calculating the keyed checksum - * over the data using specified checksum type. - * @new_cksumType the type of checksum. - * @data the data that needs to be performed a checksum calculation on. + * Verifies the keyed checksum over the data passed in. */ - // KrbSafe, KrbTgsReq - public Checksum(int new_cksumType, byte[] data, - EncryptionKey key, int usage) - throws KdcErrException, KrbApErrException, KrbCryptoException { - cksumType = new_cksumType; + public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage) + throws KdcErrException, KrbApErrException, KrbCryptoException { CksumType cksumEngine = CksumType.getInstance(cksumType); - if (!cksumEngine.isSafe()) + if (!cksumEngine.isKeyed()) { throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM); - checksum = - cksumEngine.calculateKeyedChecksum(data, - data.length, - key.getBytes(), - usage); + } else { + return cksumEngine.verifyChecksum( + data, data.length, key.getBytes(), checksum, usage); + } } + /** - * Verifies the keyed checksum over the data passed in. + * Verifies the checksum over the data passed in. The checksum might + * be a keyed or not. + * + * =============== ATTENTION! Use with care ================== + * According to https://tools.ietf.org/html/rfc3961#section-6.1, + * An unkeyed checksum should only be used "in limited circumstances + * where the lack of a key does not provide a window for an attack, + * preferably as part of an encrypted message". */ - public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, - int usage) - throws KdcErrException, KrbApErrException, KrbCryptoException { - CksumType cksumEngine = CksumType.getInstance(cksumType); - if (!cksumEngine.isSafe()) - throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM); - return cksumEngine.verifyKeyedChecksum(data, - data.length, - key.getBytes(), - checksum, - usage); + public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage) + throws KdcErrException, KrbCryptoException { + return CksumType.getInstance(cksumType).verifyChecksum( + data, data.length, key.getBytes(), checksum, usage); } - /* - public Checksum(byte[] data) throws KdcErrException, KrbCryptoException { - this(Checksum.CKSUMTYPE_DEFAULT, data); - } - */ - boolean isEqual(Checksum cksum) throws KdcErrException { - if (cksumType != cksum.cksumType) + if (cksumType != cksum.cksumType) { return false; - CksumType cksumEngine = CksumType.getInstance(cksumType); + } return CksumType.isChecksumEqual(checksum, cksum.checksum); } @@ -214,7 +211,7 @@ * @exception IOException if an I/O error occurs while reading encoded data. * */ - private Checksum(DerValue encoding) throws Asn1Exception, IOException { + public Checksum(DerValue encoding) throws Asn1Exception, IOException { DerValue der; if (encoding.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Config.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Config.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Config.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Config.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,25 +30,24 @@ */ package sun.security.krb5; -import java.io.File; -import java.io.FileInputStream; -import java.util.Hashtable; -import java.util.Vector; -import java.util.ArrayList; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.IOException; -import java.util.StringTokenizer; +import java.io.*; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.AccessController; import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Hashtable; import java.util.List; import java.util.Locale; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import sun.net.dns.ResolverConfiguration; import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.Krb5; +import sun.security.util.SecurityProperties; /** * This class maintains key-value pairs of Kerberos configurable constants @@ -57,6 +56,41 @@ public class Config { + /** + * {@systemProperty sun.security.krb5.disableReferrals} property + * indicating whether or not cross-realm referrals (RFC 6806) are + * enabled. + */ + public static final boolean DISABLE_REFERRALS; + + /** + * {@systemProperty sun.security.krb5.maxReferrals} property + * indicating the maximum number of cross-realm referral + * hops allowed. + */ + public static final int MAX_REFERRALS; + + static { + String disableReferralsProp = + SecurityProperties.privilegedGetOverridable( + "sun.security.krb5.disableReferrals"); + if (disableReferralsProp != null) { + DISABLE_REFERRALS = "true".equalsIgnoreCase(disableReferralsProp); + } else { + DISABLE_REFERRALS = false; + } + + int maxReferralsValue = 5; + String maxReferralsProp = + SecurityProperties.privilegedGetOverridable( + "sun.security.krb5.maxReferrals"); + try { + maxReferralsValue = Integer.parseInt(maxReferralsProp); + } catch (NumberFormatException e) { + } + MAX_REFERRALS = maxReferralsValue; + } + /* * Only allow a single instance of Config. */ @@ -257,7 +291,11 @@ } /** - * Gets all values for the specified keys. + * Gets all values (at least one) for the specified keys separated by + * a whitespace, or null if there is no such keys. + * The values can either be provided on a single line, or on multiple lines + * using the same key. When provided on a single line, the value can be + * comma or space separated. * @throws IllegalArgumentException if any of the keys is illegal * (See {@link #get}) */ @@ -267,6 +305,7 @@ StringBuilder sb = new StringBuilder(); boolean first = true; for (String s: v) { + s = s.replaceAll("[\\s,]+", " "); if (first) { sb.append(s); first = false; @@ -314,6 +353,72 @@ } /** + * Translates a duration value into seconds. + * + * The format can be one of "h:m[:s]", "NdNhNmNs", and "N". See + * http://web.mit.edu/kerberos/krb5-devel/doc/basic/date_format.html#duration + * for definitions. + * + * @param s the string duration + * @return time in seconds + * @throw KrbException if format is illegal + */ + public static int duration(String s) throws KrbException { + + if (s.isEmpty()) { + throw new KrbException("Duration cannot be empty"); + } + + // N + if (s.matches("\\d+")) { + return Integer.parseInt(s); + } + + // h:m[:s] + Matcher m = Pattern.compile("(\\d+):(\\d+)(:(\\d+))?").matcher(s); + if (m.matches()) { + int hr = Integer.parseInt(m.group(1)); + int min = Integer.parseInt(m.group(2)); + if (min >= 60) { + throw new KrbException("Illegal duration format " + s); + } + int result = hr * 3600 + min * 60; + if (m.group(4) != null) { + int sec = Integer.parseInt(m.group(4)); + if (sec >= 60) { + throw new KrbException("Illegal duration format " + s); + } + result += sec; + } + return result; + } + + // NdNhNmNs + // 120m allowed. Maybe 1h120m is not good, but still allowed + m = Pattern.compile( + "((\\d+)d)?\\s*((\\d+)h)?\\s*((\\d+)m)?\\s*((\\d+)s)?", + Pattern.CASE_INSENSITIVE).matcher(s); + if (m.matches()) { + int result = 0; + if (m.group(2) != null) { + result += 86400 * Integer.parseInt(m.group(2)); + } + if (m.group(4) != null) { + result += 3600 * Integer.parseInt(m.group(4)); + } + if (m.group(6) != null) { + result += 60 * Integer.parseInt(m.group(6)); + } + if (m.group(8) != null) { + result += Integer.parseInt(m.group(8)); + } + return result; + } + + throw new KrbException("Illegal duration format " + s); + } + + /** * Gets the int value for the specified keys. * @param keys the keys * @return the int value, Integer.MIN_VALUE is returned if it cannot be diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Credentials.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Credentials.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/Credentials.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/Credentials.java 2020-01-15 20:05:09.000000000 +0000 @@ -48,7 +48,9 @@ Ticket ticket; PrincipalName client; + PrincipalName clientAlias; PrincipalName server; + PrincipalName serverAlias; EncryptionKey key; TicketFlags flags; KerberosTime authTime; @@ -78,7 +80,9 @@ public Credentials(Ticket new_ticket, PrincipalName new_client, + PrincipalName new_client_alias, PrincipalName new_server, + PrincipalName new_server_alias, EncryptionKey new_key, TicketFlags new_flags, KerberosTime authTime, @@ -87,14 +91,17 @@ KerberosTime renewTill, HostAddresses cAddr, AuthorizationData authzData) { - this(new_ticket, new_client, new_server, new_key, new_flags, - authTime, new_startTime, new_endTime, renewTill, cAddr); + this(new_ticket, new_client, new_client_alias, new_server, + new_server_alias, new_key, new_flags, authTime, + new_startTime, new_endTime, renewTill, cAddr); this.authzData = authzData; } public Credentials(Ticket new_ticket, PrincipalName new_client, + PrincipalName new_client_alias, PrincipalName new_server, + PrincipalName new_server_alias, EncryptionKey new_key, TicketFlags new_flags, KerberosTime authTime, @@ -104,7 +111,9 @@ HostAddresses cAddr) { ticket = new_ticket; client = new_client; + clientAlias = new_client_alias; server = new_server; + serverAlias = new_server_alias; key = new_key; flags = new_flags; this.authTime = authTime; @@ -116,7 +125,9 @@ public Credentials(byte[] encoding, String client, + String clientAlias, String server, + String serverAlias, byte[] keyBytes, int keyType, boolean[] flags, @@ -127,7 +138,11 @@ InetAddress[] cAddrs) throws KrbException, IOException { this(new Ticket(encoding), new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL), + (clientAlias == null? null : new PrincipalName(clientAlias, + PrincipalName.KRB_NT_PRINCIPAL)), new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST), + (serverAlias == null? null : new PrincipalName(serverAlias, + PrincipalName.KRB_NT_SRV_INST)), new EncryptionKey(keyType, keyBytes), (flags == null? null: new TicketFlags(flags)), (authTime == null? null: new KerberosTime(authTime)), @@ -152,10 +167,18 @@ return client; } + public final PrincipalName getClientAlias() { + return clientAlias; + } + public final PrincipalName getServer() { return server; } + public final PrincipalName getServerAlias() { + return serverAlias; + } + public final EncryptionKey getSessionKey() { return key; } @@ -271,6 +294,7 @@ return new KrbTgsReq(options, this, server, + serverAlias, null, // from null, // till null, // rtime @@ -488,7 +512,11 @@ public static void printDebug(Credentials c) { System.out.println(">>> DEBUG: ----Credentials----"); System.out.println("\tclient: " + c.client.toString()); + if (c.clientAlias != null) + System.out.println("\tclient alias: " + c.clientAlias.toString()); System.out.println("\tserver: " + c.server.toString()); + if (c.serverAlias != null) + System.out.println("\tserver alias: " + c.serverAlias.toString()); System.out.println("\tticket: sname: " + c.ticket.sname.toString()); if (c.startTime != null) { System.out.println("\tstartTime: " + c.startTime.getTime()); @@ -516,7 +544,11 @@ public String toString() { StringBuffer buffer = new StringBuffer("Credentials:"); buffer.append( "\n client=").append(client); + if (clientAlias != null) + buffer.append( "\n clientAlias=").append(clientAlias); buffer.append( "\n server=").append(server); + if (serverAlias != null) + buffer.append( "\n serverAlias=").append(serverAlias); if (authTime != null) { buffer.append("\n authTime=").append(authTime); } @@ -531,4 +563,23 @@ return buffer.toString(); } + public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() { + return new sun.security.krb5.internal.ccache.Credentials( + getClient(), getServer(), + getSessionKey(), + date2kt(getAuthTime()), + date2kt(getStartTime()), + date2kt(getEndTime()), + date2kt(getRenewTill()), + false, + flags, + new HostAddresses(getClientAddresses()), + getAuthzData(), + getTicket(), + null); + } + + private static KerberosTime date2kt(Date d) { + return d == null ? null : new KerberosTime(d); + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java 2020-01-15 20:05:09.000000000 +0000 @@ -128,7 +128,7 @@ length--; for (int i = 0; i <= length; i++) { namelength = readLength4(); - byte[] bytes = IOUtils.readFully(this, namelength, true); + byte[] bytes = IOUtils.readExactlyNBytes(this, namelength); result.add(new String(bytes)); } if (result.isEmpty()) { @@ -186,7 +186,7 @@ if (version == KRB5_FCC_FVNO_3) read(2); /* keytype recorded twice in fvno 3 */ keyLen = readLength4(); - byte[] bytes = IOUtils.readFully(this, keyLen, true); + byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen); return new EncryptionKey(bytes, keyType, new Integer(version)); } @@ -239,7 +239,7 @@ for (int i = 0; i < num; i++) { adtype = read(2); adlength = readLength4(); - data = IOUtils.readFully(this, adlength, true); + data = IOUtils.readExactlyNBytes(this, adlength); auData.add(new AuthorizationDataEntry(adtype, data)); } return auData.toArray(new AuthorizationDataEntry[auData.size()]); @@ -253,7 +253,7 @@ if (length == 0) { return null; } else { - return IOUtils.readFully(this, length, true); + return IOUtils.readExactlyNBytes(this, length); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java 2020-01-15 20:05:09.000000000 +0000 @@ -192,8 +192,9 @@ // is most likely to be the one in Authenticator in PA-TGS-REQ encoded // in TGS-REQ, therefore only stored with a service ticket. Currently // in Java, we only reads TGTs. - return new sun.security.krb5.Credentials(ticket, - cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); + return new sun.security.krb5.Credentials(ticket, cname, null, sname, + null, key, flags, authtime, starttime, endtime, renewTill, + caddr); } public KerberosTime getStartTime() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ import sun.security.krb5.*; import java.io.IOException; +import java.util.LinkedList; +import java.util.List; /** * This class is a utility that contains much of the TGS-Exchange @@ -61,13 +63,11 @@ if (!ccreds.isForwardable()) { throw new KrbException("S4U2self needs a FORWARDABLE ticket"); } - KrbTgsReq req = new KrbTgsReq( - ccreds, - ccreds.getClient(), - new PAData(Krb5.PA_FOR_USER, - new PAForUserEnc(client, - ccreds.getSessionKey()).asn1Encode())); - Credentials creds = req.sendAndGetCreds(); + Credentials creds = serviceCreds(KDCOptions.with(KDCOptions.FORWARDABLE), + ccreds, ccreds.getClient(), ccreds.getClient(), null, + new PAData[] {new PAData(Krb5.PA_FOR_USER, + new PAForUserEnc(client, + ccreds.getSessionKey()).asn1Encode())}); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2self request not honored by KDC"); } @@ -89,11 +89,10 @@ String backend, Ticket second, PrincipalName client, Credentials ccreds) throws KrbException, IOException { - KrbTgsReq req = new KrbTgsReq( - ccreds, - second, - new PrincipalName(backend)); - Credentials creds = req.sendAndGetCreds(); + Credentials creds = serviceCreds(KDCOptions.with( + KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE), + ccreds, ccreds.getClient(), new PrincipalName(backend), + new Ticket[] {second}, null); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2proxy request not honored by KDC"); } @@ -114,53 +113,9 @@ public static Credentials acquireServiceCreds( String service, Credentials ccreds) throws KrbException, IOException { - PrincipalName sname = new PrincipalName(service); - String serviceRealm = sname.getRealmString(); - String localRealm = ccreds.getClient().getRealmString(); - - if (localRealm.equals(serviceRealm)) { - if (DEBUG) { - System.out.println( - ">>> Credentials acquireServiceCreds: same realm"); - } - return serviceCreds(sname, ccreds); - } - Credentials theCreds = null; - - boolean[] okAsDelegate = new boolean[1]; - Credentials theTgt = getTGTforRealm(localRealm, serviceRealm, - ccreds, okAsDelegate); - if (theTgt != null) { - if (DEBUG) { - System.out.println(">>> Credentials acquireServiceCreds: " - + "got right tgt"); - System.out.println(">>> Credentials acquireServiceCreds: " - + "obtaining service creds for " + sname); - } - - try { - theCreds = serviceCreds(sname, theTgt); - } catch (Exception exc) { - if (DEBUG) { - System.out.println(exc); - } - theCreds = null; - } - } - - if (theCreds != null) { - if (DEBUG) { - System.out.println(">>> Credentials acquireServiceCreds: " - + "returning creds:"); - Credentials.printDebug(theCreds); - } - if (!okAsDelegate[0]) { - theCreds.resetDelegate(); - } - return theCreds; - } - throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED, - "No service creds"); + PrincipalName sname = new PrincipalName(service, + PrincipalName.KRB_NT_SRV_HST); + return serviceCreds(sname, ccreds); } /** @@ -305,6 +260,153 @@ private static Credentials serviceCreds( PrincipalName service, Credentials ccreds) throws KrbException, IOException { - return new KrbTgsReq(ccreds, service).sendAndGetCreds(); + return serviceCreds(new KDCOptions(), ccreds, + ccreds.getClient(), service, null, null); + } + + /* + * Obtains credentials for a service (TGS). + * Cross-realm referrals are handled if enabled. A fallback scheme + * without cross-realm referrals supports is used in case of server + * error to maintain backward compatibility. + */ + private static Credentials serviceCreds( + KDCOptions options, Credentials asCreds, + PrincipalName cname, PrincipalName sname, + Ticket[] additionalTickets, PAData[] extraPAs) + throws KrbException, IOException { + if (!Config.DISABLE_REFERRALS) { + try { + return serviceCredsReferrals(options, asCreds, + cname, sname, additionalTickets, extraPAs); + } catch (KrbException e) { + // Server may raise an error if CANONICALIZE is true. + // Try CANONICALIZE false. + } + } + return serviceCredsSingle(options, asCreds, cname, + asCreds.getClientAlias(), sname, sname, additionalTickets, + extraPAs); + } + + /* + * Obtains credentials for a service (TGS). + * May handle and follow cross-realm referrals as defined by RFC 6806. + */ + private static Credentials serviceCredsReferrals( + KDCOptions options, Credentials asCreds, + PrincipalName cname, PrincipalName sname, + Ticket[] additionalTickets, PAData[] extraPAs) + throws KrbException, IOException { + options = new KDCOptions(options.toBooleanArray()); + options.set(KDCOptions.CANONICALIZE, true); + PrincipalName cSname = sname; + PrincipalName refSname = sname; // May change with referrals + Credentials creds = null; + boolean isReferral = false; + List referrals = new LinkedList<>(); + PrincipalName clientAlias = asCreds.getClientAlias(); + while (referrals.size() <= Config.MAX_REFERRALS) { + ReferralsCache.ReferralCacheEntry ref = + ReferralsCache.get(cname, sname, refSname.getRealmString()); + String toRealm = null; + if (ref == null) { + creds = serviceCredsSingle(options, asCreds, cname, + clientAlias, refSname, cSname, additionalTickets, + extraPAs); + PrincipalName server = creds.getServer(); + if (!refSname.equals(server)) { + String[] serverNameStrings = server.getNameStrings(); + if (serverNameStrings.length == 2 && + serverNameStrings[0].equals( + PrincipalName.TGS_DEFAULT_SRV_NAME) && + !refSname.getRealmAsString().equals(serverNameStrings[1])) { + // Server Name (sname) has the following format: + // krbtgt/TO-REALM.COM@FROM-REALM.COM + ReferralsCache.put(cname, sname, server.getRealmString(), + serverNameStrings[1], creds); + toRealm = serverNameStrings[1]; + isReferral = true; + asCreds = creds; + } + } + } else { + toRealm = ref.getToRealm(); + asCreds = ref.getCreds(); + isReferral = true; + } + if (isReferral) { + if (referrals.contains(toRealm)) { + // Referrals loop detected + return null; + } + refSname = new PrincipalName(refSname.getNameString(), + refSname.getNameType(), toRealm); + referrals.add(toRealm); + isReferral = false; + continue; + } + break; + } + return creds; + } + + /* + * Obtains credentials for a service (TGS). + * If the service realm is different than the one in the TGT, a new TGT for + * the service realm is obtained first (see getTGTforRealm call). This is + * not expected when following cross-realm referrals because the referral + * TGT realm matches the service realm. + */ + private static Credentials serviceCredsSingle( + KDCOptions options, Credentials asCreds, + PrincipalName cname, PrincipalName clientAlias, + PrincipalName refSname, PrincipalName sname, + Ticket[] additionalTickets, PAData[] extraPAs) + throws KrbException, IOException { + Credentials theCreds = null; + boolean[] okAsDelegate = new boolean[]{true}; + String[] serverAsCredsNames = asCreds.getServer().getNameStrings(); + String tgtRealm = serverAsCredsNames[1]; + String serviceRealm = refSname.getRealmString(); + if (!serviceRealm.equals(tgtRealm)) { + // This is a cross-realm service request + if (DEBUG) { + System.out.println(">>> serviceCredsSingle:" + + " cross-realm authentication"); + System.out.println(">>> serviceCredsSingle:" + + " obtaining credentials from " + tgtRealm + + " to " + serviceRealm); + } + Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm, + asCreds, okAsDelegate); + if (newTgt == null) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED, + "No service creds"); + } + if (DEBUG) { + System.out.println(">>> Cross-realm TGT Credentials" + + " serviceCredsSingle: "); + Credentials.printDebug(newTgt); + } + asCreds = newTgt; + cname = asCreds.getClient(); + } else if (DEBUG) { + System.out.println(">>> Credentials serviceCredsSingle:" + + " same realm"); + } + KrbTgsReq req = new KrbTgsReq(options, asCreds, cname, clientAlias, + refSname, sname, additionalTickets, extraPAs); + theCreds = req.sendAndGetCreds(); + if (theCreds != null) { + if (DEBUG) { + System.out.println(">>> TGS credentials serviceCredsSingle:"); + Credentials.printDebug(theCreds); + } + if (!okAsDelegate[0]) { + theCreds.resetDelegate(); + } + } + return theCreds; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,7 @@ package sun.security.krb5.internal.crypto; -import sun.security.krb5.Config; import sun.security.krb5.Checksum; -import sun.security.krb5.EncryptedData; -import sun.security.krb5.KrbException; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; @@ -81,6 +78,7 @@ cksumTypeName = "sun.security.krb5.internal.crypto.HmacSha1Aes128CksumType"; break; + case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256: cksumType = new HmacSha1Aes256CksumType(); cksumTypeName = @@ -117,32 +115,11 @@ return cksumType; } - - /** - * Returns default checksum type. - */ - public static CksumType getInstance() throws KdcErrException { - // this method provided for Kerberos applications. - int cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default - try { - Config c = Config.getInstance(); - if ((cksumType = (Config.getType(c.get("libdefaults", - "ap_req_checksum_type")))) == - 1) { - if ((cksumType = Config.getType(c.get("libdefaults", - "checksum_type"))) == -1) { - cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default - } - } - } catch (KrbException e) { - } - return getInstance(cksumType); - } - public abstract int confounderSize(); public abstract int cksumType(); - public abstract boolean isSafe(); + public abstract boolean isKeyed(); public abstract int cksumSize(); @@ -150,13 +127,12 @@ public abstract int keySize(); - public abstract byte[] calculateChecksum(byte[] data, int size) - throws KrbCryptoException; - - public abstract byte[] calculateKeyedChecksum(byte[] data, int size, + // Note: key and usage will be ignored for an unkeyed checksum. + public abstract byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException; - public abstract boolean verifyKeyedChecksum(byte[] data, int size, + // Note: key and usage will be ignored for an unkeyed checksum. + public abstract boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException; public static boolean isChecksumEqual(byte[] cksum1, byte[] cksum2) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -32,7 +32,6 @@ import sun.security.krb5.*; import sun.security.krb5.internal.*; -import java.util.zip.CRC32; public class Crc32CksumType extends CksumType { @@ -47,7 +46,7 @@ return Checksum.CKSUMTYPE_CRC32; } - public boolean isSafe() { + public boolean isKeyed() { return false; } @@ -63,18 +62,15 @@ return 0; } - public byte[] calculateChecksum(byte[] data, int size) { + public byte[] calculateChecksum(byte[] data, int size, + byte[] key, int usage) { return crc32.byte2crc32sum_bytes(data, size); } - public byte[] calculateKeyedChecksum(byte[] data, int size, - byte[] key, int usage) { - return null; - } - - public boolean verifyKeyedChecksum(byte[] data, int size, - byte[] key, byte[] checksum, int usage) { - return false; + public boolean verifyChecksum(byte[] data, int size, + byte[] key, byte[] checksum, int usage) { + return CksumType.isChecksumEqual(checksum, + crc32.byte2crc32sum_bytes(data)); } public static byte[] int2quad(long input) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java 2020-01-15 20:05:09.000000000 +0000 @@ -53,7 +53,7 @@ } public int checksumType() { - return Checksum.CKSUMTYPE_CRC32; + return Checksum.CKSUMTYPE_RSA_MD5; } public int checksumSize() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -49,7 +49,7 @@ return Checksum.CKSUMTYPE_DES_MAC; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -65,10 +65,6 @@ return 8; } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -78,7 +74,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { byte[] new_data = new byte[size + confounderSize()]; byte[] conf = Confounder.bytes(confounderSize()); @@ -130,7 +126,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { byte[] cksum = decryptKeyedChecksum(checksum, key); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -48,7 +48,7 @@ return Checksum.CKSUMTYPE_DES_MAC_K; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -64,10 +64,6 @@ return 8; } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -77,7 +73,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { //check for weak keys try { @@ -93,9 +89,9 @@ return cksum; } - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { - byte[] new_cksum = calculateKeyedChecksum(data, data.length, key, usage); + byte[] new_cksum = calculateChecksum(data, data.length, key, usage); return isChecksumEqual(checksum, new_cksum); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/EType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/EType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/EType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/EType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * 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,6 +301,26 @@ return isSupported(eTypeConst, enabledETypes); } + /** + * https://tools.ietf.org/html/rfc4120#section-3.1.3: + * + * A "newer" enctype is any enctype first officially + * specified concurrently with or subsequent to the issue of this RFC. + * The enctypes DES, 3DES, or RC4 and any defined in [RFC1510] are not + * "newer" enctypes. + * + * @param eTypeConst the encryption type + * @return true if "newer" + */ + public static boolean isNewer(int eTypeConst) { + return eTypeConst != EncryptedData.ETYPE_DES_CBC_CRC && + eTypeConst != EncryptedData.ETYPE_DES_CBC_MD4 && + eTypeConst != EncryptedData.ETYPE_DES_CBC_MD5 && + eTypeConst != EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD && + eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC && + eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC_EXP; + } + public static String toString(int type) { switch (type) { case 0: diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import sun.security.krb5.Checksum; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; -import javax.crypto.spec.DESKeySpec; -import java.security.InvalidKeyException; import java.security.GeneralSecurityException; /** @@ -51,7 +49,7 @@ return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -67,10 +65,6 @@ return 16; // bytes } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -78,7 +72,7 @@ * @param key the key used to encrypt the checksum. * @return keyed checksum. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { try { @@ -98,7 +92,7 @@ * @param checksum * @return true if verification is successful. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { try { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * 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,8 +28,6 @@ import sun.security.krb5.Checksum; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; -import javax.crypto.spec.DESKeySpec; -import java.security.InvalidKeyException; import java.security.GeneralSecurityException; /* @@ -51,7 +49,7 @@ return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -67,10 +65,6 @@ return 16; // bytes } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -78,7 +72,7 @@ * @param key the key used to encrypt the checksum. * @return keyed checksum. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { try { @@ -98,7 +92,7 @@ * @param checksum * @return true if verification is successful. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { try { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * 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,8 +28,6 @@ import sun.security.krb5.Checksum; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; -import javax.crypto.spec.DESKeySpec; -import java.security.InvalidKeyException; import java.security.GeneralSecurityException; /* @@ -51,7 +49,7 @@ return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -67,10 +65,6 @@ return 32; // bytes } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -78,7 +72,7 @@ * @param key the key used to encrypt the checksum. * @return keyed checksum. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { try { @@ -98,7 +92,7 @@ * @param checksum * @return true if verification is successful. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { try { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * 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,8 +28,6 @@ import sun.security.krb5.Checksum; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; -import javax.crypto.spec.DESKeySpec; -import java.security.InvalidKeyException; import java.security.GeneralSecurityException; public class HmacSha1Des3KdCksumType extends CksumType { @@ -45,7 +43,7 @@ return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -61,10 +59,6 @@ return 24; // bytes } - public byte[] calculateChecksum(byte[] data, int size) { - return null; - } - /** * Calculates keyed checksum. * @param data the data used to generate the checksum. @@ -72,7 +66,7 @@ * @param key the key used to encrypt the checksum. * @return keyed checksum. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { try { @@ -92,7 +86,7 @@ * @param checksum * @return true if verification is successful. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { try { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * 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,6 +56,7 @@ public static final int KU_KRB_SAFE_CKSUM = 15; // KrbSafe public static final int KU_PA_FOR_USER_ENC_CKSUM = 17; // S4U2user public static final int KU_AD_KDC_ISSUED_CKSUM = 19; + public static final int KU_AS_REQ = 56; public static final boolean isValid(int usage) { return usage >= 0; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,8 +33,6 @@ import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; import java.security.MessageDigest; -import java.security.Provider; -import java.security.Security; public final class RsaMd5CksumType extends CksumType { @@ -49,7 +47,7 @@ return Checksum.CKSUMTYPE_RSA_MD5; } - public boolean isSafe() { + public boolean isKeyed() { return false; } @@ -74,7 +72,8 @@ * @modified by Yanni Zhang, 12/08/99. */ - public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{ + public byte[] calculateChecksum(byte[] data, int size, + byte[] key, int usage) throws KrbCryptoException{ MessageDigest md5; byte[] result = null; try { @@ -91,14 +90,15 @@ return result; } - public byte[] calculateKeyedChecksum(byte[] data, int size, - byte[] key, int usage) throws KrbCryptoException { - return null; - } - - public boolean verifyKeyedChecksum(byte[] data, int size, - byte[] key, byte[] checksum, int usage) throws KrbCryptoException { - return false; + @Override + public boolean verifyChecksum(byte[] data, int size, + byte[] key, byte[] checksum, int usage) + throws KrbCryptoException { + try { + byte[] calculated = MessageDigest.getInstance("MD5").digest(data); + return CksumType.isChecksumEqual(calculated, checksum); + } catch (Exception e) { + return false; + } } - } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,12 +33,8 @@ import sun.security.krb5.Confounder; import sun.security.krb5.KrbCryptoException; import sun.security.krb5.internal.*; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; import javax.crypto.spec.DESKeySpec; import java.security.MessageDigest; -import java.security.Provider; -import java.security.Security; import java.security.InvalidKeyException; public final class RsaMd5DesCksumType extends CksumType { @@ -54,7 +50,7 @@ return Checksum.CKSUMTYPE_RSA_MD5_DES; } - public boolean isSafe() { + public boolean isKeyed() { return true; } @@ -79,7 +75,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key, + public byte[] calculateChecksum(byte[] data, int size, byte[] key, int usage) throws KrbCryptoException { //prepend confounder byte[] new_data = new byte[size + confounderSize()]; @@ -88,7 +84,7 @@ System.arraycopy(data, 0, new_data, confounderSize(), size); //calculate md5 cksum - byte[] mdc_cksum = calculateChecksum(new_data, new_data.length); + byte[] mdc_cksum = calculateRawChecksum(new_data, new_data.length); byte[] cksum = new byte[cksumSize()]; System.arraycopy(conf, 0, cksum, 0, confounderSize()); System.arraycopy(mdc_cksum, 0, cksum, confounderSize(), @@ -125,7 +121,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public boolean verifyKeyedChecksum(byte[] data, int size, + public boolean verifyChecksum(byte[] data, int size, byte[] key, byte[] checksum, int usage) throws KrbCryptoException { //decrypt checksum byte[] cksum = decryptKeyedChecksum(checksum, key); @@ -135,7 +131,7 @@ System.arraycopy(cksum, 0, new_data, 0, confounderSize()); System.arraycopy(data, 0, new_data, confounderSize(), size); - byte[] new_cksum = calculateChecksum(new_data, new_data.length); + byte[] new_cksum = calculateRawChecksum(new_data, new_data.length); //extract original cksum value byte[] orig_cksum = new byte[cksumSize() - confounderSize()]; System.arraycopy(cksum, confounderSize(), orig_cksum, 0, @@ -181,7 +177,7 @@ * * @modified by Yanni Zhang, 12/08/99. */ - public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{ + private byte[] calculateRawChecksum(byte[] data, int size) throws KrbCryptoException{ MessageDigest md5; byte[] result = null; try { @@ -197,5 +193,4 @@ } return result; } - } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncASRepPart.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncASRepPart.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncASRepPart.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncASRepPart.java 2020-01-15 20:05:09.000000000 +0000 @@ -47,7 +47,8 @@ KerberosTime new_endtime, KerberosTime new_renewTill, PrincipalName new_sname, - HostAddresses new_caddr) { + HostAddresses new_caddr, + PAData[] new_pAData) { super( new_key, new_lastReq, @@ -60,6 +61,7 @@ new_renewTill, new_sname, new_caddr, + new_pAData, Krb5.KRB_ENC_AS_REP_PART ); //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java 2020-01-15 20:05:09.000000000 +0000 @@ -31,7 +31,6 @@ package sun.security.krb5.internal; import sun.security.krb5.*; -import sun.security.krb5.EncryptionKey; import sun.security.util.*; import java.util.Vector; import java.io.IOException; @@ -41,19 +40,20 @@ * Implements the ASN.1 EncKDCRepPart type. * *

    - * EncKDCRepPart ::= SEQUENCE { - * key [0] EncryptionKey, - * last-req [1] LastReq, - * nonce [2] UInt32, - * key-expiration [3] KerberosTime OPTIONAL, - * flags [4] TicketFlags, - * authtime [5] KerberosTime, - * starttime [6] KerberosTime OPTIONAL, - * endtime [7] KerberosTime, - * renew-till [8] KerberosTime OPTIONAL, - * srealm [9] Realm, - * sname [10] PrincipalName, - * caddr [11] HostAddresses OPTIONAL + * EncKDCRepPart ::= SEQUENCE { + * key [0] EncryptionKey, + * last-req [1] LastReq, + * nonce [2] UInt32, + * key-expiration [3] KerberosTime OPTIONAL, + * flags [4] TicketFlags, + * authtime [5] KerberosTime, + * starttime [6] KerberosTime OPTIONAL, + * endtime [7] KerberosTime, + * renew-till [8] KerberosTime OPTIONAL, + * srealm [9] Realm, + * sname [10] PrincipalName, + * caddr [11] HostAddresses OPTIONAL, + * encrypted-pa-data [12] SEQUENCE OF PA-DATA OPTIONAL * } * * @@ -76,6 +76,7 @@ public KerberosTime renewTill; //optional public PrincipalName sname; public HostAddresses caddr; //optional + public PAData[] pAData; //optional public int msgType; //not included in sequence public EncKDCRepPart( @@ -90,6 +91,7 @@ KerberosTime new_renewTill, PrincipalName new_sname, HostAddresses new_caddr, + PAData[] new_pAData, int new_msgType) { key = new_key; lastReq = new_lastReq; @@ -102,6 +104,7 @@ renewTill = new_renewTill; sname = new_sname; caddr = new_caddr; + pAData = new_pAData; msgType = new_msgType; } @@ -160,6 +163,9 @@ if (der.getData().available() > 0) { caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true); } + if (der.getData().available() > 0) { + pAData = PAData.parseSequence(der.getData(), (byte) 0x0C, true); + } // We observe extra data from MSAD /*if (der.getData().available() > 0) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); @@ -175,47 +181,58 @@ */ public byte[] asn1Encode(int rep_type) throws Asn1Exception, IOException { + DerOutputStream bytes; DerOutputStream temp = new DerOutputStream(); - DerOutputStream bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), key.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), lastReq.asn1Encode()); temp.putInteger(BigInteger.valueOf(nonce)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), temp); if (keyExpiration != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), keyExpiration.asn1Encode()); } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), flags.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), authtime.asn1Encode()); if (starttime != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x06), starttime.asn1Encode()); } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x07), endtime.asn1Encode()); if (renewTill != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x08), renewTill.asn1Encode()); } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x09), sname.getRealm().asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x0A), sname.asn1Encode()); if (caddr != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x0B), caddr.asn1Encode()); } + if (pAData != null && pAData.length > 0) { + temp = new DerOutputStream(); + for (int i = 0; i < pAData.length; i++) { + temp.write(pAData[i].asn1Encode()); + } + bytes = new DerOutputStream(); + bytes.write(DerValue.tag_SequenceOf, temp); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0C), bytes); + } //should use the rep_type to build the encoding //but other implementations do not; it is ignored and //the cached msgType is used instead temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); + temp.write(DerValue.tag_Sequence, out); bytes = new DerOutputStream(); bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) msgType), temp); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java 2020-01-15 20:05:09.000000000 +0000 @@ -46,7 +46,8 @@ KerberosTime new_endtime, KerberosTime new_renewTill, PrincipalName new_sname, - HostAddresses new_caddr) { + HostAddresses new_caddr, + PAData[] new_pAData) { super( new_key, new_lastReq, @@ -59,6 +60,7 @@ new_renewTill, new_sname, new_caddr, + new_pAData, Krb5.KRB_ENC_TGS_REP_PART); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddresses.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddresses.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddresses.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddresses.java 2020-01-15 20:05:09.000000000 +0000 @@ -31,16 +31,14 @@ package sun.security.krb5.internal; +import sun.security.krb5.Config; import sun.security.krb5.PrincipalName; import sun.security.krb5.KrbException; import sun.security.krb5.Asn1Exception; import sun.security.util.*; -import java.util.Vector; -import java.util.ArrayList; -import java.net.InetAddress; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.UnknownHostException; + +import java.net.*; +import java.util.*; import java.io.IOException; import sun.security.krb5.internal.ccache.CCacheOutputStream; @@ -250,6 +248,10 @@ */ public void writeAddrs(CCacheOutputStream cos) throws IOException { + if (addresses == null || addresses.length == 0) { + cos.write32(0); + return; + } cos.write32(addresses.length); for (int i = 0; i < addresses.length; i++) { cos.write16(addresses[i].addrType); @@ -289,34 +291,35 @@ */ public static HostAddresses getLocalAddresses() throws IOException { - String hostname = null; - InetAddress[] inetAddresses = null; + Set all = new LinkedHashSet<>(); try { - InetAddress localHost = InetAddress.getLocalHost(); - hostname = localHost.getHostName(); - inetAddresses = InetAddress.getAllByName(hostname); - HostAddress[] hAddresses = new HostAddress[inetAddresses.length]; - for (int i = 0; i < inetAddresses.length; i++) - { - hAddresses[i] = new HostAddress(inetAddresses[i]); - } if (DEBUG) { - System.out.println(">>> KrbKdcReq local addresses for " - + hostname + " are: "); - - for (int i = 0; i < inetAddresses.length; i++) { - System.out.println("\n\t" + inetAddresses[i]); - if (inetAddresses[i] instanceof Inet4Address) - System.out.println("IPv4 address"); - if (inetAddresses[i] instanceof Inet6Address) - System.out.println("IPv6 address"); + System.out.println(">>> KrbKdcReq local addresses are:"); + } + String extra = Config.getInstance().getAll( + "libdefaults", "extra_addresses"); + if (extra != null) { + for (String s: extra.split("\\s+")) { + all.add(InetAddress.getByName(s)); + if (DEBUG) { + System.out.println(" extra_addresses: " + + InetAddress.getByName(s)); + } } } - return (new HostAddresses(hAddresses)); + for (NetworkInterface ni: + Collections.list(NetworkInterface.getNetworkInterfaces())) { + if (DEBUG) { + System.out.println(" NetworkInterface " + ni + ":"); + System.out.println(" " + + Collections.list(ni.getInetAddresses())); + } + all.addAll(Collections.list(ni.getInetAddresses())); + } + return new HostAddresses(all.toArray(new InetAddress[all.size()])); } catch (Exception exc) { throw new IOException(exc.toString()); } - } /** @@ -335,4 +338,9 @@ for (int i = 0; i < inetAddresses.length; i++) addresses[i] = new HostAddress(inetAddresses[i]); } + + @Override + public String toString() { + return Arrays.toString(addresses); + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddress.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddress.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddress.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/HostAddress.java 2020-01-15 20:05:09.000000000 +0000 @@ -39,6 +39,7 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.io.IOException; +import java.util.Arrays; /** * Implements the ASN.1 HostAddress type. @@ -295,4 +296,11 @@ } } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(Arrays.toString(address)); + sb.append('(').append(addrType).append(')'); + return sb.toString(); + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCOptions.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCOptions.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCOptions.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCOptions.java 2020-01-15 20:05:09.000000000 +0000 @@ -140,6 +140,7 @@ public static final int UNUSED10 = 10; public static final int UNUSED11 = 11; public static final int CNAME_IN_ADDL_TKT = 14; + public static final int CANONICALIZE = 15; public static final int RENEWABLE_OK = 27; public static final int ENC_TKT_IN_SKEY = 28; public static final int RENEW = 30; @@ -160,7 +161,8 @@ "UNUSED11", //11; null,null, "CNAME_IN_ADDL_TKT",//14; - null,null,null,null,null,null,null,null,null,null,null,null, + "CANONICALIZE", //15; + null,null,null,null,null,null,null,null,null,null,null, "RENEWABLE_OK", //27; "ENC_TKT_IN_SKEY", //28; null, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCReq.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCReq.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCReq.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KDCReq.java 2020-01-15 20:05:09.000000000 +0000 @@ -59,9 +59,9 @@ public class KDCReq { public KDCReqBody reqBody; + public PAData[] pAData = null; //optional private int pvno; private int msgType; - private PAData[] pAData = null; //optional public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody, int req_type) throws IOException { @@ -144,23 +144,7 @@ } else { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - if ((der.getData().peekByte() & 0x1F) == 0x03) { - subDer = der.getData().getDerValue(); - DerValue subsubDer = subDer.getData().getDerValue(); - if (subsubDer.getTag() != DerValue.tag_SequenceOf) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - Vector v = new Vector<>(); - while (subsubDer.getData().available() > 0) { - v.addElement(new PAData(subsubDer.getData().getDerValue())); - } - if (v.size() > 0) { - pAData = new PAData[v.size()]; - v.copyInto(pAData); - } - } else { - pAData = null; - } + pAData = PAData.parseSequence(der.getData(), (byte) 0x03, true); subDer = der.getData().getDerValue(); if ((subDer.getTag() & 0x01F) == 0x04) { DerValue subsubDer = subDer.getData().getDerValue(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KerberosTime.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KerberosTime.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KerberosTime.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KerberosTime.java 2020-01-15 20:05:09.000000000 +0000 @@ -38,6 +38,7 @@ import sun.security.util.DerValue; import java.io.IOException; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; @@ -129,6 +130,14 @@ } /** + * Creates a KerberosTime object from an Instant object + */ + public KerberosTime(Instant instant) { + this(instant.getEpochSecond()*1000 + instant.getNano()/1000000L, + instant.getNano()/1000%1000); + } + + /** * Creates a KerberosTime object for now. It uses System.nanoTime() * to get a more precise time than "new Date()". */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/Krb5.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/Krb5.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/Krb5.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/Krb5.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,6 +70,7 @@ public static final int TKT_OPTS_PRE_AUTHENT = 10; public static final int TKT_OPTS_HW_AUTHENT = 11; public static final int TKT_OPTS_DELEGATE = 13; + public static final int TKT_OPTS_ENC_PA_REP = 15; public static final int TKT_OPTS_MAX = 31; // KDC Options @@ -163,6 +164,9 @@ // S4U2user info public static final int PA_FOR_USER = 129; + // FAST (RFC 6806) + public static final int PA_REQ_ENC_PA_REP = 149; + //-------------------------------+------------- //authorization data type |ad-type value //-------------------------------+------------- @@ -265,6 +269,7 @@ public static final int KRB_ERR_RESPONSE_TOO_BIG = 52; //Response too big for UDP, retry with TCP public static final int KRB_ERR_GENERIC = 60; //Generic error (description in e-text) public static final int KRB_ERR_FIELD_TOOLONG = 61; //Field is too long for this implementation + public static final int KRB_ERR_WRONG_REALM = 68; //Wrong realm public static final int KRB_CRYPTO_NOT_SUPPORT = 100; //Client does not support this crypto type public static final int KRB_AP_ERR_NOREALM = 62; public static final int KRB_AP_ERR_GEN_CRED = 63; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KRBError.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KRBError.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KRBError.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/KRBError.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,6 +90,7 @@ private KerberosTime sTime; private Integer suSec; private int errorCode; + private Realm crealm; //optional private PrincipalName cname; //optional private PrincipalName sname; private String eText; //optional @@ -138,6 +139,7 @@ sTime = new_sTime; suSec = new_suSec; errorCode = new_errorCode; + crealm = new_cname != null ? new_cname.getRealm() : null; cname = new_cname; sname = new_sname; eText = new_eText; @@ -166,6 +168,7 @@ sTime = new_sTime; suSec = new_suSec; errorCode = new_errorCode; + crealm = new_cname != null ? new_cname.getRealm() : null; cname = new_cname; sname = new_sname; eText = new_eText; @@ -262,6 +265,10 @@ pa = paList.toArray(new PAData[paList.size()]); } + public final Realm getClientRealm() { + return crealm; + } + public final KerberosTime getServerTime() { return sTime; } @@ -349,7 +356,7 @@ errorCode = subDer.getData().getBigInteger().intValue(); } else throw new Asn1Exception(Krb5.ASN1_BAD_ID); - Realm crealm = Realm.parse(der.getData(), (byte)0x07, true); + crealm = Realm.parse(der.getData(), (byte)0x07, true); cname = PrincipalName.parse(der.getData(), (byte)0x08, true, crealm); Realm realm = Realm.parse(der.getData(), (byte)0x09, false); sname = PrincipalName.parse(der.getData(), (byte)0x0A, false, realm); @@ -393,6 +400,9 @@ System.out.println("\t suSec is " + suSec); System.out.println("\t error code is " + errorCode); System.out.println("\t error Message is " + Krb5.getErrorMessage(errorCode)); + if (crealm != null) { + System.out.println("\t crealm is " + crealm.toString()); + } if (cname != null) { System.out.println("\t cname is " + cname.toString()); } @@ -442,8 +452,10 @@ temp.putInteger(BigInteger.valueOf(errorCode)); bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), temp); + if (crealm != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), crealm.asn1Encode()); + } if (cname != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), cname.getRealm().asn1Encode()); bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), cname.asn1Encode()); } @@ -488,6 +500,7 @@ isEqual(sTime, other.sTime) && isEqual(suSec, other.suSec) && errorCode == other.errorCode && + isEqual(crealm, other.crealm) && isEqual(cname, other.cname) && isEqual(sname, other.sname) && isEqual(eText, other.eText) && @@ -508,6 +521,7 @@ if (sTime != null) result = 37 * result + sTime.hashCode(); if (suSec != null) result = 37 * result + suSec.hashCode(); result = 37 * result + errorCode; + if (crealm != null) result = 37 * result + crealm.hashCode(); if (cname != null) result = 37 * result + cname.hashCode(); if (sname != null) result = 37 * result + sname.hashCode(); if (eText != null) result = 37 * result + eText.hashCode(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/NetClient.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/NetClient.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/NetClient.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/NetClient.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,7 +103,7 @@ } try { - return IOUtils.readFully(in, len, true); + return IOUtils.readExactlyNBytes(in, len); } catch (IOException ioe) { if (Krb5.DEBUG) { System.out.println( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAData.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAData.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAData.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAData.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,4 +1,6 @@ /* + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,10 +32,12 @@ package sun.security.krb5.internal; -import sun.security.krb5.KrbException; +import sun.security.krb5.internal.crypto.EType; import sun.security.util.*; import sun.security.krb5.Asn1Exception; import java.io.IOException; +import java.util.Vector; + import sun.security.krb5.internal.util.KerberosString; /** @@ -139,6 +143,41 @@ } /** + * Parse (unmarshal) a PAData from a DER input stream. This form + * parsing might be used when expanding a value which is part of + * a constructed sequence and uses explicitly tagged type. + * + * @exception Asn1Exception if an Asn1Exception occurs. + * @param data the Der input stream value, which contains one or more + * marshaled values. + * @param explicitTag tag number. + * @param optional indicates if this data field is optional. + * @return an array of PAData. + */ + public static PAData[] parseSequence(DerInputStream data, + byte explicitTag, boolean optional) + throws Asn1Exception, IOException { + if ((optional) && + (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) + return null; + DerValue subDer = data.getDerValue(); + DerValue subsubDer = subDer.getData().getDerValue(); + if (subsubDer.getTag() != DerValue.tag_SequenceOf) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + Vector v = new Vector<>(); + while (subsubDer.getData().available() > 0) { + v.addElement(new PAData(subsubDer.getData().getDerValue())); + } + if (v.size() > 0) { + PAData[] pas = new PAData[v.size()]; + v.copyInto(pas); + return pas; + } + return null; + } + + /** * Gets the preferred etype from the PAData array. * 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored * 2. ETYPE-INFO2 preferred to ETYPE-INFO @@ -169,8 +208,8 @@ while (d2.data.available() > 0) { DerValue value = d2.data.getDerValue(); ETypeInfo2 tmp = new ETypeInfo2(value); - if (tmp.getParams() == null) { - // we don't support non-null s2kparams + if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) { + // we don't support non-null s2kparams for old etypes return tmp.getEType(); } } @@ -236,8 +275,9 @@ while (d2.data.available() > 0) { DerValue value = d2.data.getDerValue(); ETypeInfo2 tmp = new ETypeInfo2(value); - if (tmp.getParams() == null && tmp.getEType() == eType) { - // we don't support non-null s2kparams + if (tmp.getEType() == eType && + (EType.isNewer(eType) || tmp.getParams() == null)) { + // we don't support non-null s2kparams for old etypes return new SaltAndParams(tmp.getSalt(), tmp.getParams()); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,7 @@ bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode()); try { + // MS-SFU 2.2.1: use hmac-md5 checksum regardless of key type Checksum cks = new Checksum( Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR, getS4UByteArray(), diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ReferralsCache.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ReferralsCache.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ReferralsCache.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/ReferralsCache.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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.krb5.internal; + +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import sun.security.krb5.Credentials; +import sun.security.krb5.PrincipalName; + +/* + * ReferralsCache class implements a cache scheme for referral TGTs as + * described in RFC 6806 - 10. Caching Information. The goal is to optimize + * resources (such as network traffic) when a client requests credentials for a + * service principal to a given KDC. If a referral TGT was previously received, + * cached information is used instead of issuing a new query. Once a referral + * TGT expires, the corresponding referral entry in the cache is removed. + */ +final class ReferralsCache { + + private static Map> + referralsMap = new HashMap<>(); + + static private final class ReferralCacheKey { + private PrincipalName cname; + private PrincipalName sname; + ReferralCacheKey (PrincipalName cname, PrincipalName sname) { + this.cname = cname; + this.sname = sname; + } + public boolean equals(Object other) { + if (!(other instanceof ReferralCacheKey)) + return false; + ReferralCacheKey that = (ReferralCacheKey)other; + return cname.equals(that.cname) && + sname.equals(that.sname); + } + public int hashCode() { + return cname.hashCode() + sname.hashCode(); + } + } + + static final class ReferralCacheEntry { + private final Credentials creds; + private final String toRealm; + ReferralCacheEntry(Credentials creds, String toRealm) { + this.creds = creds; + this.toRealm = toRealm; + } + Credentials getCreds() { + return creds; + } + String getToRealm() { + return toRealm; + } + } + + /* + * Add a new referral entry to the cache, including: client principal, + * service principal, source KDC realm, destination KDC realm and + * referral TGT. + * + * If a loop is generated when adding the new referral, the first hop is + * automatically removed. For example, let's assume that adding a + * REALM-3.COM -> REALM-1.COM referral generates the following loop: + * REALM-1.COM -> REALM-2.COM -> REALM-3.COM -> REALM-1.COM. Then, + * REALM-1.COM -> REALM-2.COM referral entry is removed from the cache. + */ + static synchronized void put(PrincipalName cname, PrincipalName service, + String fromRealm, String toRealm, Credentials creds) { + ReferralCacheKey k = new ReferralCacheKey(cname, service); + pruneExpired(k); + if (creds.getEndTime().before(new Date())) { + return; + } + Map entries = referralsMap.get(k); + if (entries == null) { + entries = new HashMap(); + referralsMap.put(k, entries); + } + entries.remove(fromRealm); + ReferralCacheEntry newEntry = new ReferralCacheEntry(creds, toRealm); + entries.put(fromRealm, newEntry); + + // Remove loops within the cache + ReferralCacheEntry current = newEntry; + List seen = new LinkedList<>(); + while (current != null) { + if (seen.contains(current)) { + // Loop found. Remove the first referral to cut the loop. + entries.remove(newEntry.getToRealm()); + break; + } + seen.add(current); + current = entries.get(current.getToRealm()); + } + } + + /* + * Obtain a referral entry from the cache given a client principal, + * service principal and a source KDC realm. + */ + static synchronized ReferralCacheEntry get(PrincipalName cname, + PrincipalName service, String fromRealm) { + ReferralCacheKey k = new ReferralCacheKey(cname, service); + pruneExpired(k); + Map entries = referralsMap.get(k); + if (entries != null) { + ReferralCacheEntry toRef = entries.get(fromRealm); + if (toRef != null) { + return toRef; + } + } + return null; + } + + /* + * Remove referral entries from the cache when referral TGTs expire. + */ + private static void pruneExpired(ReferralCacheKey k) { + Date now = new Date(); + Map entries = referralsMap.get(k); + if (entries != null) { + for (Entry mapEntry : + entries.entrySet()) { + if (mapEntry.getValue().getCreds().getEndTime().before(now)) { + entries.remove(mapEntry.getKey()); + } + } + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/TicketFlags.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/TicketFlags.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/TicketFlags.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/internal/TicketFlags.java 2020-01-15 20:05:09.000000000 +0000 @@ -51,7 +51,8 @@ * renewable(8), * initial(9), * pre-authent(10), - * hw-authent(11) + * hw-authent(11), + * enc-pa-rep(15) * } */ public class TicketFlags extends KerberosFlags { @@ -178,6 +179,9 @@ case 11: sb.append("HW-AUTHENT;"); break; + case 15: + sb.append("ENC-PA-REP;"); + break; } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java 2020-01-15 20:05:09.000000000 +0000 @@ -25,6 +25,7 @@ package sun.security.krb5; +import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.kerberos.KeyTab; @@ -39,6 +40,14 @@ public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot( KeyTab ktab); + public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t); + + public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a); + + public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t); + + public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a); + /** * Returns the proxy for a KerberosTicket. */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbApReq.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbApReq.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbApReq.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbApReq.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -361,7 +361,9 @@ creds = new Credentials( apReqMessg.ticket, authenticator.cname, + null, apReqMessg.ticket.sname, + null, enc_ticketPart.key, enc_ticketPart.flags, enc_ticketPart.authtime, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsRep.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsRep.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsRep.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsRep.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ "Cannot find key for type/kvno to decrypt AS REP - " + EType.toString(encPartKeyType) + "/" + encPartKvno); } - decrypt(dkey, asReq); + decrypt(dkey, asReq, cname); } /** @@ -136,7 +136,7 @@ password, encPartKeyType, PAData.getSaltAndParams(encPartKeyType, rep.pAData)); - decrypt(dkey, asReq); + decrypt(dkey, asReq, cname); } /** @@ -144,7 +144,8 @@ * @param dkey the decryption key to use * @param asReq the original AS-REQ sent, used to validate AS-REP */ - private void decrypt(EncryptionKey dkey, KrbAsReq asReq) + private void decrypt(EncryptionKey dkey, KrbAsReq asReq, + PrincipalName cname) throws KrbException, Asn1Exception, IOException { byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey, KeyUsage.KU_ENC_AS_REP_PART); @@ -155,12 +156,18 @@ rep.encKDCRepPart = enc_part; ASReq req = asReq.getMessage(); - check(true, req, rep); + check(true, req, rep, dkey); + + PrincipalName clientAlias = cname; + if (clientAlias.equals(rep.cname)) + clientAlias = null; creds = new Credentials( rep.ticket, - req.reqBody.cname, + rep.cname, + clientAlias, enc_part.sname, + null, // No server alias expected in a TGT enc_part.key, enc_part.flags, enc_part.authtime, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,6 +68,7 @@ // Common data for AS-REQ fields private KDCOptions options; private PrincipalName cname; + private PrincipalName refCname; // May be changed by referrals private PrincipalName sname; private KerberosTime from; private KerberosTime till; @@ -100,6 +101,7 @@ private void init(PrincipalName cname) throws KrbException { this.cname = cname; + this.refCname = cname; state = State.INIT; } @@ -224,6 +226,16 @@ this.options = options; } + public void setTill(KerberosTime till) { + checkState(State.INIT, "Cannot specify till"); + this.till = till; + } + + public void setRTime(KerberosTime rtime) { + checkState(State.INIT, "Cannot specify rtime"); + this.rtime = rtime; + } + /** * Sets or clears target. If cleared, KrbAsReq might choose krbtgt * for cname realm @@ -252,7 +264,9 @@ * @throws KrbException * @throws IOException */ - private KrbAsReq build(EncryptionKey key) throws KrbException, IOException { + private KrbAsReq build(EncryptionKey key, ReferralsState referralsState) + throws KrbException, IOException { + PAData[] extraPAs = null; int[] eTypes; if (password != null) { eTypes = EType.getDefaults("default_tkt_enctypes"); @@ -262,15 +276,24 @@ ks); for (EncryptionKey k: ks) k.destroy(); } + options = (options == null) ? new KDCOptions() : options; + if (referralsState.isEnabled()) { + options.set(KDCOptions.CANONICALIZE, true); + extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP, + new byte[]{}) }; + } else { + options.set(KDCOptions.CANONICALIZE, false); + } return new KrbAsReq(key, options, - cname, + refCname, sname, from, till, rtime, eTypes, - addresses); + addresses, + extraPAs); } /** @@ -308,11 +331,15 @@ */ private KrbAsReqBuilder send() throws KrbException, IOException { boolean preAuthFailedOnce = false; - KdcComm comm = new KdcComm(cname.getRealmAsString()); + KdcComm comm = null; EncryptionKey pakey = null; + ReferralsState referralsState = new ReferralsState(); while (true) { + if (referralsState.refreshComm()) { + comm = new KdcComm(refCname.getRealmAsString()); + } try { - req = build(pakey); + req = build(pakey, referralsState); rep = new KrbAsRep(comm.send(req.encoding())); return this; } catch (KrbException ke) { @@ -341,12 +368,71 @@ } paList = kerr.getPA(); // Update current paList } else { + if (referralsState.handleError(ke)) { + pakey = null; + preAuthFailedOnce = false; + continue; + } throw ke; } } } } + private final class ReferralsState { + private boolean enabled; + private int count; + private boolean refreshComm; + + ReferralsState() throws KrbException { + if (Config.DISABLE_REFERRALS) { + if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) { + throw new KrbException("NT-ENTERPRISE principals only allowed" + + " when referrals are enabled."); + } + enabled = false; + } else { + enabled = true; + } + refreshComm = true; + } + + boolean handleError(KrbException ke) throws RealmException { + if (enabled) { + if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) { + Realm referredRealm = ke.getError().getClientRealm(); + if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) && + referredRealm != null && referredRealm.toString().length() > 0 && + count < Config.MAX_REFERRALS) { + refCname = new PrincipalName(refCname.getNameType(), + refCname.getNameStrings(), referredRealm); + refreshComm = true; + count++; + return true; + } + } + if (count < Config.MAX_REFERRALS && + refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) { + // Server may raise an error if CANONICALIZE is true. + // Try CANONICALIZE false. + enabled = false; + return true; + } + } + return false; + } + + boolean refreshComm() { + boolean retRefreshComm = refreshComm; + refreshComm = false; + return retRefreshComm; + } + + boolean isEnabled() { + return enabled; + } + } + /** * Performs AS-REQ send and AS-REP receive. * Maybe a state is needed here, to divide prepare process and getCreds. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReq.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReq.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReq.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbAsReq.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ import sun.security.krb5.internal.crypto.Nonce; import sun.security.krb5.internal.crypto.KeyUsage; import java.io.IOException; +import java.time.Instant; +import java.util.Arrays; /** * This class encapsulates the KRB-AS-REQ message that the client @@ -57,14 +59,14 @@ KerberosTime till, // ok, will use KerberosTime rtime, // ok int[] eTypes, // NO - HostAddresses addresses // ok + HostAddresses addresses, // ok + PAData[] extraPAs // ok ) throws KrbException, IOException { if (options == null) { options = new KDCOptions(); } - // check if they are valid arguments. The optional fields should be // consistent with settings in KDCOptions. Mar 17 2000 if (options.get(KDCOptions.FORWARDED) || @@ -82,12 +84,6 @@ } else { if (from != null) from = null; } - if (options.get(KDCOptions.RENEWABLE)) { - // if (rtime == null) - // throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } else { - if (rtime != null) rtime = null; - } PAData[] paData = null; if (pakey != null) { @@ -99,6 +95,15 @@ paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP, encTs.asn1Encode()); } + if (extraPAs != null && extraPAs.length > 0) { + if (paData == null) { + paData = new PAData[extraPAs.length]; + } else { + paData = Arrays.copyOf(paData, paData.length + extraPAs.length); + } + System.arraycopy(extraPAs, 0, paData, + paData.length - extraPAs.length, extraPAs.length); + } if (cname.getRealm() == null) { throw new RealmException(Krb5.REALM_NULL, @@ -109,8 +114,10 @@ System.out.println(">>> KrbAsReq creating message"); } + Config cfg = Config.getInstance(); + // check to use addresses in tickets - if (addresses == null && Config.getInstance().useAddresses()) { + if (addresses == null && cfg.useAddresses()) { addresses = HostAddresses.getLocalAddresses(); } @@ -120,7 +127,26 @@ } if (till == null) { - till = new KerberosTime(0); // Choose KDC maximum allowed + String d = cfg.get("libdefaults", "ticket_lifetime"); + if (d != null) { + till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d))); + } else { + till = new KerberosTime(0); // Choose KDC maximum allowed + } + } + + if (rtime == null) { + String d = cfg.get("libdefaults", "renew_lifetime"); + if (d != null) { + rtime = new KerberosTime(Instant.now().plusSeconds(Config.duration(d))); + } + } + + if (rtime != null) { + options.set(KDCOptions.RENEWABLE, true); + if (till.greaterThan(rtime)) { + rtime = till; + } } // enc-authorization-data and additional-tickets never in AS-REQ diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbCred.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbCred.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbCred.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbCred.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import sun.security.krb5.internal.*; import sun.security.krb5.internal.crypto.KeyUsage; import java.io.IOException; + import sun.security.util.DerValue; /** @@ -62,7 +63,6 @@ PrincipalName client = tgt.getClient(); PrincipalName tgService = tgt.getServer(); - PrincipalName server = serviceTicket.getServer(); if (!serviceTicket.getClient().equals(client)) throw new KrbException(Krb5.KRB_ERR_GENERIC, "Client principal does not match"); @@ -75,14 +75,10 @@ options.set(KDCOptions.FORWARDED, true); options.set(KDCOptions.FORWARDABLE, true); - HostAddresses sAddrs = null; - // XXX Also NT_GSS_KRB5_PRINCIPAL can be a host based principal - // GSSName.NT_HOSTBASED_SERVICE should display with KRB_NT_SRV_HST - if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST) - sAddrs= new HostAddresses(server); - KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService, - null, null, null, null, sAddrs, null, null, null); + null, null, null, null, null, + null, // No easy way to get addresses right + null, null, null); credMessg = createMessage(tgsReq.sendAndGetCreds(), key); obuf = credMessg.asn1Encode(); @@ -94,7 +90,6 @@ EncryptionKey sessionKey = delegatedCreds.getSessionKey(); PrincipalName princ = delegatedCreds.getClient(); - Realm realm = princ.getRealm(); PrincipalName tgService = delegatedCreds.getServer(); KrbCredInfo credInfo = new KrbCredInfo(sessionKey, @@ -157,7 +152,7 @@ + " endtime=" + endtime + "renewTill=" + renewTill); } - creds = new Credentials(ticket, pname, sname, credInfoKey, + creds = new Credentials(ticket, pname, null, sname, null, credInfoKey, flags, authtime, starttime, endtime, renewTill, caddr); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbKdcRep.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbKdcRep.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbKdcRep.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbKdcRep.java 2020-01-15 20:05:09.000000000 +0000 @@ -31,23 +31,41 @@ package sun.security.krb5; import sun.security.krb5.internal.*; +import sun.security.krb5.internal.crypto.KeyUsage; +import sun.security.util.DerInputStream; abstract class KrbKdcRep { static void check( boolean isAsReq, KDCReq req, - KDCRep rep + KDCRep rep, + EncryptionKey replyKey ) throws KrbApErrException { - if (isAsReq && !req.reqBody.cname.equals(rep.cname)) { + // cname change in AS-REP is allowed only if the client + // sent CANONICALIZE and the server supports RFC 6806 - Section 11 + // FAST scheme (ENC-PA-REP flag). + if (isAsReq && !req.reqBody.cname.equals(rep.cname) && + (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) || + !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } + // sname change in TGS-REP is allowed only if client + // sent CANONICALIZE and new sname is a referral of + // the form krbtgt/TO-REALM.COM@FROM-REALM.COM. if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) { - rep.encKDCRepPart.key.destroy(); - throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); + String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings(); + if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) || + snameStrings == null || snameStrings.length != 2 || + !snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) || + !rep.encKDCRepPart.sname.getRealmString().equals( + req.reqBody.sname.getRealmString())) { + rep.encKDCRepPart.key.destroy(); + throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); + } } if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) { @@ -82,49 +100,84 @@ !rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) { throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } - if ((req.reqBody.from == null) || req.reqBody.from.isZero()) + + if ((req.reqBody.from == null) || req.reqBody.from.isZero()) { // verify this is allowed if ((rep.encKDCRepPart.starttime != null) && - !rep.encKDCRepPart.starttime.inClockSkew()) { + !rep.encKDCRepPart.starttime.inClockSkew()) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW); } + } - if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) + if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) { // verify this is allowed if ((rep.encKDCRepPart.starttime != null) && - !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) { + !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } + } if (!req.reqBody.till.isZero() && - rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) { + rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } - if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) - if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) - // verify this is required - if ((rep.encKDCRepPart.renewTill == null) || - rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime) - ) { - rep.encKDCRepPart.key.destroy(); - throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); + // RFC 6806 - Section 11 mechanism check + if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) && + req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) { + boolean reqPaReqEncPaRep = false; + boolean repPaReqEncPaRepValid = false; + + // PA_REQ_ENC_PA_REP only required for AS requests + for (PAData pa : req.pAData) { + if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) { + reqPaReqEncPaRep = true; + break; + } + } + + if (rep.encKDCRepPart.pAData != null) { + for (PAData pa : rep.encKDCRepPart.pAData) { + if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) { + try { + Checksum repCksum = new Checksum( + new DerInputStream( + pa.getValue()).getDerValue()); + // The checksum is inside encKDCRepPart so we don't + // care if it's keyed or not. + repPaReqEncPaRepValid = + repCksum.verifyAnyChecksum( + req.asn1Encode(), replyKey, + KeyUsage.KU_AS_REQ); + } catch (Exception e) { + if (Krb5.DEBUG) { + e.printStackTrace(); + } + } + break; + } } + } + + if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); + } + } - if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE_OK) && - rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) - if (!req.reqBody.till.isZero()) - // verify this is required + if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) { + if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) { + // verify this is required if ((rep.encKDCRepPart.renewTill == null) || - rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.till) - ) { + rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime) + ) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } - } - + } + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsRep.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsRep.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsRep.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsRep.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,11 +84,22 @@ EncTGSRepPart enc_part = new EncTGSRepPart(ref); rep.encKDCRepPart = enc_part; - check(false, req, rep); + check(false, req, rep, tgsReq.tgsReqKey); + + PrincipalName serverAlias = tgsReq.getServerAlias(); + if (serverAlias != null) { + PrincipalName repSname = enc_part.sname; + if (serverAlias.equals(repSname) || + isReferralSname(repSname)) { + serverAlias = null; + } + } this.creds = new Credentials(rep.ticket, rep.cname, + tgsReq.getClientAlias(), enc_part.sname, + serverAlias, enc_part.key, enc_part.flags, enc_part.authtime, @@ -111,4 +122,16 @@ sun.security.krb5.internal.ccache.Credentials setCredentials() { return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket); } + + private static boolean isReferralSname(PrincipalName sname) { + if (sname != null) { + String[] snameStrings = sname.getNameStrings(); + if (snameStrings.length == 2 && + snameStrings[0].equals( + PrincipalName.TGS_DEFAULT_SRV_NAME)) { + return true; + } + } + return false; + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsReq.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsReq.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsReq.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/KrbTgsReq.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import sun.security.krb5.internal.crypto.*; import java.io.IOException; import java.net.UnknownHostException; +import java.time.Instant; import java.util.Arrays; /** @@ -44,7 +45,9 @@ public class KrbTgsReq { private PrincipalName princName; + private PrincipalName clientAlias; private PrincipalName servName; + private PrincipalName serverAlias; private TGSReq tgsReqMessg; private KerberosTime ctime; private Ticket secondTicket = null; @@ -57,59 +60,26 @@ private byte[] ibuf; // Used in CredentialsUtil - public KrbTgsReq(Credentials asCreds, - PrincipalName sname) + public KrbTgsReq(KDCOptions options, Credentials asCreds, + PrincipalName cname, PrincipalName clientAlias, + PrincipalName sname, PrincipalName serverAlias, + Ticket[] additionalTickets, PAData[] extraPAs) throws KrbException, IOException { - this(new KDCOptions(), - asCreds, - sname, - null, // KerberosTime from - null, // KerberosTime till - null, // KerberosTime rtime - null, // eTypes, // null, // int[] eTypes - null, // HostAddresses addresses - null, // AuthorizationData authorizationData - null, // Ticket[] additionalTickets - null); // EncryptionKey subSessionKey - } - - // S4U2proxy - public KrbTgsReq(Credentials asCreds, - Ticket second, - PrincipalName sname) - throws KrbException, IOException { - this(KDCOptions.with(KDCOptions.CNAME_IN_ADDL_TKT, - KDCOptions.FORWARDABLE), - asCreds, - sname, - null, - null, - null, - null, - null, - null, - new Ticket[] {second}, // the service ticket - null); - } - - // S4U2user - public KrbTgsReq(Credentials asCreds, - PrincipalName sname, - PAData extraPA) - throws KrbException, IOException { - this(KDCOptions.with(KDCOptions.FORWARDABLE), - asCreds, - asCreds.getClient(), - sname, - null, - null, - null, - null, - null, - null, - null, - null, - extraPA); // the PA-FOR-USER + this(options, + asCreds, + cname, + clientAlias, + sname, + serverAlias, + null, // KerberosTime from + null, // KerberosTime till + null, // KerberosTime rtime + null, // int[] eTypes + null, // HostAddresses addresses + null, // AuthorizationData authorizationData + additionalTickets, + null, // EncryptionKey subKey + extraPAs); } // Called by Credentials, KrbCred @@ -117,6 +87,7 @@ KDCOptions options, Credentials asCreds, PrincipalName sname, + PrincipalName serverAlias, KerberosTime from, KerberosTime till, KerberosTime rtime, @@ -125,16 +96,18 @@ AuthorizationData authorizationData, Ticket[] additionalTickets, EncryptionKey subKey) throws KrbException, IOException { - this(options, asCreds, asCreds.getClient(), sname, - from, till, rtime, eTypes, addresses, - authorizationData, additionalTickets, subKey, null); + this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(), + sname, serverAlias, from, till, rtime, eTypes, + addresses, authorizationData, additionalTickets, subKey, null); } private KrbTgsReq( KDCOptions options, Credentials asCreds, PrincipalName cname, + PrincipalName clientAlias, PrincipalName sname, + PrincipalName serverAlias, KerberosTime from, KerberosTime till, KerberosTime rtime, @@ -143,10 +116,12 @@ AuthorizationData authorizationData, Ticket[] additionalTickets, EncryptionKey subKey, - PAData extraPA) throws KrbException, IOException { + PAData[] extraPAs) throws KrbException, IOException { princName = cname; + this.clientAlias = clientAlias; servName = sname; + this.serverAlias = serverAlias; ctime = KerberosTime.now(); // check if they are valid arguments. The optional fields @@ -216,7 +191,7 @@ authorizationData, additionalTickets, subKey, - extraPA); + extraPAs); obuf = tgsReqMessg.asn1Encode(); // XXX We need to revisit this to see if can't move it @@ -282,11 +257,16 @@ AuthorizationData authorizationData, Ticket[] additionalTickets, EncryptionKey subKey, - PAData extraPA) + PAData[] extraPAs) throws IOException, KrbException, UnknownHostException { KerberosTime req_till = null; if (till == null) { - req_till = new KerberosTime(0); + String d = Config.getInstance().get("libdefaults", "ticket_lifetime"); + if (d != null) { + req_till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d))); + } else { + req_till = new KerberosTime(0); // Choose KDC maximum allowed + } } else { req_till = till; } @@ -340,26 +320,8 @@ byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ); // if the checksum type is one of the keyed checksum types, // use session key. - Checksum cksum; - switch (Checksum.CKSUMTYPE_DEFAULT) { - case Checksum.CKSUMTYPE_RSA_MD4_DES: - case Checksum.CKSUMTYPE_DES_MAC: - case Checksum.CKSUMTYPE_DES_MAC_K: - case Checksum.CKSUMTYPE_RSA_MD4_DES_K: - case Checksum.CKSUMTYPE_RSA_MD5_DES: - case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD: - case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR: - case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128: - case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256: - cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key, + Checksum cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key, KeyUsage.KU_PA_TGS_REQ_CKSUM); - break; - case Checksum.CKSUMTYPE_CRC32: - case Checksum.CKSUMTYPE_RSA_MD4: - case Checksum.CKSUMTYPE_RSA_MD5: - default: - cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp); - } // Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR @@ -375,11 +337,14 @@ null).getMessage(); PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req); - return new TGSReq( - extraPA != null ? - new PAData[] {extraPA, tgsPAData } : - new PAData[] {tgsPAData}, - reqBody); + PAData[] pa; + if (extraPAs != null) { + pa = Arrays.copyOf(extraPAs, extraPAs.length + 1); + pa[extraPAs.length] = tgsPAData; + } else { + pa = new PAData[] {tgsPAData}; + } + return new TGSReq(pa, reqBody); } TGSReq getMessage() { @@ -390,6 +355,14 @@ return secondTicket; } + PrincipalName getClientAlias() { + return clientAlias; + } + + PrincipalName getServerAlias() { + return serverAlias; + } + private static void debug(String message) { // System.err.println(">>> KrbTgsReq: " + message); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/PrincipalName.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/PrincipalName.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/krb5/PrincipalName.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/krb5/PrincipalName.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,6 +91,11 @@ public static final int KRB_NT_UID = 5; /** + * Enterprise name (alias) + */ + public static final int KRB_NT_ENTERPRISE = 10; + + /** * TGS Name */ public static final String TGS_DEFAULT_SRV_NAME = "krbtgt"; @@ -454,6 +459,7 @@ case KRB_NT_SRV_INST: case KRB_NT_SRV_XHST: case KRB_NT_UID: + case KRB_NT_ENTERPRISE: nameStrings = nameParts; nameType = type; if (realm != null) { @@ -547,7 +553,9 @@ for (int i = 0; i < nameStrings.length; i++) { if (i > 0) str.append("/"); - str.append(nameStrings[i]); + String n = nameStrings[i]; + n = n.replace("@", "\\@"); + str.append(n); } str.append("@"); str.append(nameRealm.toString()); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2020-01-15 20:05:09.000000000 +0000 @@ -982,7 +982,7 @@ new CertEntry((X509Certificate) cert, null, alias, AnyUsage, attributes); certificateCount++; - entries.put(alias, certEntry); + entries.put(alias.toLowerCase(Locale.ENGLISH), certEntry); if (debug != null) { debug.println("Setting a trusted certificate at alias '" + alias + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyChecker.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyChecker.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyChecker.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyChecker.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -578,7 +578,7 @@ } /** - * Rewrite leaf nodes at the end of validation as described in RFC 3280 + * Rewrite leaf nodes at the end of validation as described in RFC 5280 * section 6.1.5: Step (g)(iii). Leaf nodes with anyPolicy are replaced * by nodes explicitly representing initial policies not already * represented by leaf nodes. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ private PolicyNodeImpl mParent; private HashSet mChildren; - // the 4 fields specified by RFC 3280 + // the 4 fields specified by RFC 5280 private String mValidPolicy; private HashSet mQualifierSet; private boolean mCriticalityIndicator; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/JavaKeyStore.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/JavaKeyStore.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/JavaKeyStore.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/JavaKeyStore.java 2020-01-15 20:05:09.000000000 +0000 @@ -691,7 +691,7 @@ // Read the private key entry.protectedPrivKey = - IOUtils.readFully(dis, dis.readInt(), true); + IOUtils.readExactlyNBytes(dis, dis.readInt()); // Read the certificate chain int numOfCerts = dis.readInt(); @@ -716,7 +716,7 @@ } } // instantiate the certificate - encoded = IOUtils.readFully(dis, dis.readInt(), true); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); certs.add(cf.generateCertificate(bais)); bais.close(); @@ -755,7 +755,7 @@ cfs.put(certType, cf); } } - encoded = IOUtils.readFully(dis, dis.readInt(), true); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); entry.cert = cf.generateCertificate(bais); bais.close(); @@ -776,16 +776,13 @@ if (password != null) { byte computed[], actual[]; computed = md.digest(); - actual = new byte[computed.length]; - dis.readFully(actual); - for (int i = 0; i < computed.length; i++) { - if (computed[i] != actual[i]) { - Throwable t = new UnrecoverableKeyException + actual = IOUtils.readExactlyNBytes(dis, computed.length); + if (!MessageDigest.isEqual(computed, actual)) { + Throwable t = new UnrecoverableKeyException ("Password verification failed"); - throw (IOException)new IOException + throw (IOException) new IOException ("Keystore was tampered with, or " - + "password was incorrect").initCause(t); - } + + "password was incorrect").initCause(t); } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/SunEntries.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/SunEntries.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/provider/SunEntries.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/provider/SunEntries.java 2020-01-15 20:05:09.000000000 +0000 @@ -65,7 +65,7 @@ * and CRLs. Aliases for X.509 are X509. * * - PKIX is the certification path validation algorithm described - * in RFC 3280. The ValidationAlgorithm attribute notes the + * in RFC 5280. The ValidationAlgorithm attribute notes the * specification that this provider implements. * * - LDAP is the CertStore type for LDAP repositories. The @@ -257,7 +257,7 @@ map.put("CertPathBuilder.PKIX", "sun.security.provider.certpath.SunCertPathBuilder"); map.put("CertPathBuilder.PKIX ValidationAlgorithm", - "RFC3280"); + "RFC5280"); /* * CertPathValidator @@ -265,7 +265,7 @@ map.put("CertPathValidator.PKIX", "sun.security.provider.certpath.PKIXCertPathValidator"); map.put("CertPathValidator.PKIX ValidationAlgorithm", - "RFC3280"); + "RFC5280"); /* * CertStores diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/timestamp/HttpTimestamper.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/timestamp/HttpTimestamper.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/timestamp/HttpTimestamper.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/timestamp/HttpTimestamper.java 2020-01-15 20:05:09.000000000 +0000 @@ -27,6 +27,7 @@ import java.io.BufferedInputStream; import java.io.DataOutputStream; +import java.io.EOFException; import java.io.IOException; import java.net.URI; import java.net.URL; @@ -147,8 +148,11 @@ } verifyMimeType(connection.getContentType()); - int contentLength = connection.getContentLength(); - replyBuffer = IOUtils.readFully(input, contentLength, false); + int clen = connection.getContentLength(); + replyBuffer = IOUtils.readAllBytes(input); + if (clen != -1 && replyBuffer.length != clen) + throw new EOFException("Expected:" + clen + + ", read:" + replyBuffer.length); if (debug != null) { debug.println("received timestamp response (length=" + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java 2020-01-15 20:05:09.000000000 +0000 @@ -144,7 +144,7 @@ /** * Examine the certificate for a Subject Information Access extension - * (RFC 3280). + * (RFC 5280). * The extension's {@code accessMethod} field should contain the object * identifier defined for timestamping: 1.3.6.1.5.5.7.48.3 and its * {@code accessLocation} field should contain an HTTP or HTTPS URL. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerInputBuffer.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerInputBuffer.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerInputBuffer.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerInputBuffer.java 2020-01-15 20:05:09.000000000 +0000 @@ -300,7 +300,7 @@ * YYMMDDhhmmss-hhmm * UTC Time is broken in storing only two digits of year. * If YY < 50, we assume 20YY; - * if YY >= 50, we assume 19YY, as per RFC 3280. + * if YY >= 50, we assume 19YY, as per RFC 5280. * * Generalized time has a four-digit year and allows any * precision specified in ISO 8601. However, for our purposes, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerOutputStream.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerOutputStream.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerOutputStream.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerOutputStream.java 2020-01-15 20:05:09.000000000 +0000 @@ -461,7 +461,7 @@ * Marshals a DER UTC time/date value. * *

    YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time - * and with seconds (even if seconds=0) as per RFC 3280. + * and with seconds (even if seconds=0) as per RFC 5280. */ public void putUTCTime(Date d) throws IOException { putTime(d, DerValue.tag_UtcTime); @@ -471,7 +471,7 @@ * Marshals a DER Generalized Time/date value. * *

    YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time - * and with seconds (even if seconds=0) as per RFC 3280. + * and with seconds (even if seconds=0) as per RFC 5280. */ public void putGeneralizedTime(Date d) throws IOException { putTime(d, DerValue.tag_GeneralizedTime); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerValue.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerValue.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/util/DerValue.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/util/DerValue.java 2020-01-15 20:05:09.000000000 +0000 @@ -45,8 +45,8 @@ * (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data). * * A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3 - * and RFC 3280, section 4.1.2.4., we assume that this kind of string will - * contain ISO-8859-1 characters only. + * and RFC 5280, section 8, we assume that this kind of string will contain + * ISO-8859-1 characters only. * * * @author David Brownell @@ -409,7 +409,7 @@ if (fullyBuffered && in.available() != length) throw new IOException("extra data given to DerValue constructor"); - byte[] bytes = IOUtils.readFully(in, length, true); + byte[] bytes = IOUtils.readExactlyNBytes(in, length); buffer = new DerInputBuffer(bytes, allowBER); return new DerInputStream(buffer); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/validator/PKIXValidator.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/validator/PKIXValidator.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/validator/PKIXValidator.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/validator/PKIXValidator.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import javax.security.auth.x500.X500Principal; import sun.security.action.GetBooleanAction; +import sun.security.action.GetPropertyAction; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.provider.certpath.PKIXExtendedParameters; @@ -64,6 +65,18 @@ // enable use of the validator if possible private final static boolean TRY_VALIDATOR = true; + /** + * System property that if set (or set to "true"), allows trust anchor + * certificates to be used if they do not have the proper CA extensions. + * Set to false if prop is not set, or set to any other value. + */ + private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor(); + private static boolean allowNonCaAnchor() { + String prop = GetPropertyAction + .privilegedGetProperty("jdk.security.allowNonCaAnchor"); + return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true")); + } + private final Set trustedCerts; private final PKIXBuilderParameters parameterTemplate; private int certPathLength = -1; @@ -209,6 +222,7 @@ ("null or zero-length certificate chain"); } + // Use PKIXExtendedParameters for timestamp and variant additions PKIXBuilderParameters pkixParameters = null; try { @@ -234,29 +248,30 @@ for (int i = 0; i < chain.length; i++) { X509Certificate cert = chain[i]; X500Principal dn = cert.getSubjectX500Principal(); - if (i != 0 && - !dn.equals(prevIssuer)) { - // chain is not ordered correctly, call builder instead - return doBuild(chain, otherCerts, pkixParameters); - } - // Check if chain[i] is already trusted. It may be inside - // trustedCerts, or has the same dn and public key as a cert - // inside trustedCerts. The latter happens when a CA has - // updated its cert with a stronger signature algorithm in JRE - // but the weak one is still in circulation. - - if (trustedCerts.contains(cert) || // trusted cert - (trustedSubjects.containsKey(dn) && // replacing ... - trustedSubjects.get(dn).contains( // ... weak cert - cert.getPublicKey()))) { - if (i == 0) { + if (i == 0) { + if (trustedCerts.contains(cert)) { return new X509Certificate[] {chain[0]}; } - // Remove and call validator on partial chain [0 .. i-1] - X509Certificate[] newChain = new X509Certificate[i]; - System.arraycopy(chain, 0, newChain, 0, i); - return doValidate(newChain, pkixParameters); + } else { + if (!dn.equals(prevIssuer)) { + // chain is not ordered correctly, call builder instead + return doBuild(chain, otherCerts, pkixParameters); + } + // Check if chain[i] is already trusted. It may be inside + // trustedCerts, or has the same dn and public key as a cert + // inside trustedCerts. The latter happens when a CA has + // updated its cert with a stronger signature algorithm in JRE + // but the weak one is still in circulation. + if (trustedCerts.contains(cert) || // trusted cert + (trustedSubjects.containsKey(dn) && // replacing ... + trustedSubjects.get(dn).contains( // ... weak cert + cert.getPublicKey()))) { + // Remove and call validator on partial chain [0 .. i-1] + X509Certificate[] newChain = new X509Certificate[i]; + System.arraycopy(chain, 0, newChain, 0, i); + return doValidate(newChain, pkixParameters); + } } prevIssuer = cert.getIssuerX500Principal(); } @@ -320,15 +335,18 @@ private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor) throws CertificateException { - List list = - path.getCertificates(); - X509Certificate[] chain = new X509Certificate[list.size() + 1]; - list.toArray(chain); X509Certificate trustedCert = anchor.getTrustedCert(); if (trustedCert == null) { throw new ValidatorException ("TrustAnchor must be specified as certificate"); } + + verifyTrustAnchor(trustedCert); + + List list = + path.getCertificates(); + X509Certificate[] chain = new X509Certificate[list.size() + 1]; + list.toArray(chain); chain[chain.length - 1] = trustedCert; return chain; } @@ -363,6 +381,41 @@ } } + /** + * Verify that a trust anchor certificate is a CA certificate. + */ + private static void verifyTrustAnchor(X509Certificate trustedCert) + throws ValidatorException { + + // skip check if jdk.security.allowNonCAAnchor system property is set + if (ALLOW_NON_CA_ANCHOR) { + return; + } + + // allow v1 trust anchor certificates + if (trustedCert.getVersion() < 3) { + return; + } + + // check that the BasicConstraints cA field is not set to false + if (trustedCert.getBasicConstraints() == -1) { + throw new ValidatorException + ("TrustAnchor with subject \"" + + trustedCert.getSubjectX500Principal() + + "\" is not a CA certificate"); + } + + // check that the KeyUsage extension, if included, asserts the + // keyCertSign bit + boolean[] keyUsageBits = trustedCert.getKeyUsage(); + if (keyUsageBits != null && !keyUsageBits[5]) { + throw new ValidatorException + ("TrustAnchor with subject \"" + + trustedCert.getSubjectX500Principal() + + "\" does not have keyCertSign bit set in KeyUsage extension"); + } + } + private X509Certificate[] doBuild(X509Certificate[] chain, Collection otherCerts, PKIXBuilderParameters params) throws CertificateException { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * certificate that identifies the specific OCSP Responder to use when * performing on-line validation of that certificate. *

    - * This extension is defined in + * This extension is defined in * Internet X.509 PKI Certificate and Certificate Revocation List * (CRL) Profile. The profile permits * the extension to be included in end-entity or CA certificates, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/AVA.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/AVA.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/AVA.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/AVA.java 2020-01-15 20:05:09.000000000 +0000 @@ -599,7 +599,7 @@ if (derval.tag != DerValue.tag_Sequence) { throw new IOException("AVA not a sequence"); } - oid = X500Name.intern(derval.data.getOID()); + oid = derval.data.getOID(); value = derval.data.getDerValue(); if (derval.data.available() != 0) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/CertificateIssuerExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/CertificateIssuerExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/CertificateIssuerExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/CertificateIssuerExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ *

    * If used by conforming CRL issuers, this extension is always * critical. If an implementation ignored this extension it could not - * correctly attribute CRL entries to certificates. PKIX (RFC 3280) + * correctly attribute CRL entries to certificates. PKIX (RFC 5280) * RECOMMENDS that implementations recognize this extension. *

    * The ASN.1 definition for this is: diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * *

    * The extension is defined in Section 5.2.4 of - * Internet X.509 PKI Certific + * Internet X.509 PKI Certific ate and Certificate Revocation List (CRL) Profile. * *

    diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * 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,7 +94,7 @@ public static final String NAME = "ExtendedKeyUsage"; public static final String USAGES = "usages"; - // OID defined in RFC 3280 Sections 4.2.1.13 + // OID defined in RFC 5280 Sections 4.2.1.12 // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html private static final Map map = new HashMap (); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/FreshestCRLExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/FreshestCRLExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/FreshestCRLExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/FreshestCRLExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * *

    * The extension is defined in Section 5.2.6 of - * Internet X.509 PKI Certific + * Internet X.509 PKI Certific ate and Certificate Revocation List (CRL) Profile. * *

    diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/InvalidityDateExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/InvalidityDateExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/InvalidityDateExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/InvalidityDateExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ import sun.security.util.*; /** - * From RFC 3280: + * From RFC 5280: *

    * The invalidity date is a non-critical CRL entry extension that * provides the date on which it is known or suspected that the private diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * *

    * The extension is defined in Section 5.2.5 of - * Internet X.509 PKI Certific + * Internet X.509 PKI Certific ate and Certificate Revocation List (CRL) Profile. * *

    diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/RDN.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/RDN.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/RDN.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/RDN.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -343,7 +343,7 @@ /* * Returns a printable form of this RDN, using RFC 1779 style catenation * of attribute/value assertions, and emitting attribute type keywords - * from RFCs 1779, 2253, and 3280. + * from RFCs 1779, 2253, and 5280. */ public String toString() { if (assertion.length == 1) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/README openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/README --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/README 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/README 2020-01-15 20:05:09.000000000 +0000 @@ -34,7 +34,7 @@ Protocol (LDAP) that many organizations are expecting will help address online certificate distribution over the Internet. - RFC 3280, which describes the Internet X.509 Public Key + RFC 5280, which describes the Internet X.509 Public Key Infrastructure Certificate and CRL Profile. RSA DSI has a bunch of "Public Key Cryptography Standards" (PKCS) which diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ * included in end entity or CA certificates. Conforming CAs MUST mark * this extension as non-critical. *

    - * This extension is defined in + * This extension is defined in * Internet X.509 PKI Certificate and Certificate Revocation List * (CRL) Profile. The profile permits * the extension to be included in end-entity or CA certificates, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/URIName.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/URIName.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/URIName.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/URIName.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * This class implements the URIName as required by the GeneralNames * ASN.1 object. *

    - * [RFC3280] When the subjectAltName extension contains a URI, the name MUST be + * [RFC5280] When the subjectAltName extension contains a URI, the name MUST be * stored in the uniformResourceIdentifier (an IA5String). The name MUST * be a non-relative URL, and MUST follow the URL syntax and encoding - * rules specified in [RFC 1738]. The name must include both a scheme + * rules specified in [RFC 3986]. The name must include both a scheme * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme- * specific-part must include a fully qualified domain name or IP * address as the host. *

    - * As specified in [RFC 1738], the scheme name is not case-sensitive + * As specified in [RFC 3986], the scheme name is not case-sensitive * (e.g., "http" is equivalent to "HTTP"). The host part is also not * case-sensitive, but other components of the scheme-specific-part may * be case-sensitive. When comparing URIs, conforming implementations @@ -113,7 +113,7 @@ } host = uri.getHost(); - // RFC 3280 says that the host should be non-null, but we allow it to + // RFC 5280 says that the host should be non-null, but we allow it to // be null because some widely deployed certificates contain CDP // extensions with URIs that have no hostname (see bugs 4802236 and // 5107944). @@ -148,7 +148,7 @@ /** * Create the URIName object with the specified name constraint. URI * name constraints syntax is different than SubjectAltNames, etc. See - * 4.2.1.11 of RFC 3280. + * 4.2.1.10 of RFC 5280. * * @param value the URI name constraint * @throws IOException if name is not a proper URI name constraint @@ -300,7 +300,7 @@ * These results are used in checking NameConstraints during * certification path verification. *

    - * RFC3280: For URIs, the constraint applies to the host part of the name. + * RFC5280: For URIs, the constraint applies to the host part of the name. * The constraint may specify a host or a domain. Examples would be * "foo.bar.com"; and ".xyz.com". When the the constraint begins with * a period, it may be expanded with one or more subdomains. That is, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X500Name.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X500Name.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X500Name.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X500Name.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -604,7 +604,7 @@ * Returns a string form of the X.500 distinguished name. * The format of the string is from RFC 1779. The returned string * may contain non-standardised keywords for more readability - * (keywords from RFCs 1779, 2253, and 3280). + * (keywords from RFCs 1779, 2253, and 5280). */ public String toString() { if (dn == null) { @@ -865,7 +865,7 @@ * O="Sue, Grabbit and Runn" or * O=Sue\, Grabbit and Runn * - * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 3280 + * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 5280 * keywords. Additional keywords can be specified in the keyword/OID map. */ private void parseDN(String input, Map keywordMap) @@ -1104,20 +1104,8 @@ /****************************************************************/ /* - * Maybe return a preallocated OID, to reduce storage costs - * and speed recognition of common X.500 attributes. - */ - static ObjectIdentifier intern(ObjectIdentifier oid) { - ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid); - return (interned == null) ? oid : interned; - } - - private static final Map internedOIDs - = new HashMap(); - - /* * Selected OIDs from X.520 - * Includes all those specified in RFC 3280 as MUST or SHOULD + * Includes all those specified in RFC 5280 as MUST or SHOULD * be recognized */ private static final int commonName_data[] = { 2, 5, 4, 3 }; @@ -1142,92 +1130,82 @@ { 0, 9, 2342, 19200300, 100, 1, 1 }; - public static final ObjectIdentifier commonName_oid; - public static final ObjectIdentifier countryName_oid; - public static final ObjectIdentifier localityName_oid; - public static final ObjectIdentifier orgName_oid; - public static final ObjectIdentifier orgUnitName_oid; - public static final ObjectIdentifier stateName_oid; - public static final ObjectIdentifier streetAddress_oid; - public static final ObjectIdentifier title_oid; - public static final ObjectIdentifier DNQUALIFIER_OID; - public static final ObjectIdentifier SURNAME_OID; - public static final ObjectIdentifier GIVENNAME_OID; - public static final ObjectIdentifier INITIALS_OID; - public static final ObjectIdentifier GENERATIONQUALIFIER_OID; - public static final ObjectIdentifier ipAddress_oid; - public static final ObjectIdentifier DOMAIN_COMPONENT_OID; - public static final ObjectIdentifier userid_oid; - public static final ObjectIdentifier SERIALNUMBER_OID; - - static { - /** OID for the "CN=" attribute, denoting a person's common name. */ - commonName_oid = intern(ObjectIdentifier.newInternal(commonName_data)); - - /** OID for the "SERIALNUMBER=" attribute, denoting a serial number for. - a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the - certificate serial number. */ - SERIALNUMBER_OID = intern(ObjectIdentifier.newInternal(SERIALNUMBER_DATA)); - - /** OID for the "C=" attribute, denoting a country. */ - countryName_oid = intern(ObjectIdentifier.newInternal(countryName_data)); - - /** OID for the "L=" attribute, denoting a locality (such as a city) */ - localityName_oid = intern(ObjectIdentifier.newInternal(localityName_data)); - - /** OID for the "O=" attribute, denoting an organization name */ - orgName_oid = intern(ObjectIdentifier.newInternal(orgName_data)); - - /** OID for the "OU=" attribute, denoting an organizational unit name */ - orgUnitName_oid = intern(ObjectIdentifier.newInternal(orgUnitName_data)); - - /** OID for the "S=" attribute, denoting a state (such as Delaware) */ - stateName_oid = intern(ObjectIdentifier.newInternal(stateName_data)); - - /** OID for the "STREET=" attribute, denoting a street address. */ - streetAddress_oid = intern(ObjectIdentifier.newInternal(streetAddress_data)); - - /** OID for the "T=" attribute, denoting a person's title. */ - title_oid = intern(ObjectIdentifier.newInternal(title_data)); - - /** OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN - disambiguating information.*/ - DNQUALIFIER_OID = intern(ObjectIdentifier.newInternal(DNQUALIFIER_DATA)); - - /** OID for the "SURNAME=" attribute, denoting a person's surname.*/ - SURNAME_OID = intern(ObjectIdentifier.newInternal(SURNAME_DATA)); - - /** OID for the "GIVENNAME=" attribute, denoting a person's given name.*/ - GIVENNAME_OID = intern(ObjectIdentifier.newInternal(GIVENNAME_DATA)); - - /** OID for the "INITIALS=" attribute, denoting a person's initials.*/ - INITIALS_OID = intern(ObjectIdentifier.newInternal(INITIALS_DATA)); - - /** OID for the "GENERATION=" attribute, denoting Jr., II, etc.*/ - GENERATIONQUALIFIER_OID = - intern(ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA)); - - /* - * OIDs from other sources which show up in X.500 names we - * expect to deal with often - */ - /** OID for "IP=" IP address attributes, used with SKIP. */ - ipAddress_oid = intern(ObjectIdentifier.newInternal(ipAddress_data)); - - /* - * Domain component OID from RFC 1274, RFC 2247, RFC 3280 - */ - - /* - * OID for "DC=" domain component attributes, used with DNSNames in DN - * format - */ - DOMAIN_COMPONENT_OID = - intern(ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA)); - - /** OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. */ - userid_oid = intern(ObjectIdentifier.newInternal(userid_data)); - } + // OID for the "CN=" attribute, denoting a person's common name. + public static final ObjectIdentifier commonName_oid = + ObjectIdentifier.newInternal(commonName_data); + + // OID for the "SERIALNUMBER=" attribute, denoting a serial number for. + // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the + // certificate serial number. + public static final ObjectIdentifier SERIALNUMBER_OID = + ObjectIdentifier.newInternal(SERIALNUMBER_DATA); + + // OID for the "C=" attribute, denoting a country. + public static final ObjectIdentifier countryName_oid = + ObjectIdentifier.newInternal(countryName_data); + + // OID for the "L=" attribute, denoting a locality (such as a city). + public static final ObjectIdentifier localityName_oid = + ObjectIdentifier.newInternal(localityName_data); + + // OID for the "O=" attribute, denoting an organization name. + public static final ObjectIdentifier orgName_oid = + ObjectIdentifier.newInternal(orgName_data); + + // OID for the "OU=" attribute, denoting an organizational unit name. + public static final ObjectIdentifier orgUnitName_oid = + ObjectIdentifier.newInternal(orgUnitName_data); + + // OID for the "S=" attribute, denoting a state (such as Delaware). + public static final ObjectIdentifier stateName_oid = + ObjectIdentifier.newInternal(stateName_data); + + // OID for the "STREET=" attribute, denoting a street address. + public static final ObjectIdentifier streetAddress_oid = + ObjectIdentifier.newInternal(streetAddress_data); + + // OID for the "T=" attribute, denoting a person's title. + public static final ObjectIdentifier title_oid = + ObjectIdentifier.newInternal(title_data); + + // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN + // disambiguating information. + public static final ObjectIdentifier DNQUALIFIER_OID = + ObjectIdentifier.newInternal(DNQUALIFIER_DATA); + + // OID for the "SURNAME=" attribute, denoting a person's surname. + public static final ObjectIdentifier SURNAME_OID = + ObjectIdentifier.newInternal(SURNAME_DATA); + + // OID for the "GIVENNAME=" attribute, denoting a person's given name. + public static final ObjectIdentifier GIVENNAME_OID = + ObjectIdentifier.newInternal(GIVENNAME_DATA); + + // OID for the "INITIALS=" attribute, denoting a person's initials. + public static final ObjectIdentifier INITIALS_OID = + ObjectIdentifier.newInternal(INITIALS_DATA); + + // OID for the "GENERATION=" attribute, denoting Jr., II, etc. + public static final ObjectIdentifier GENERATIONQUALIFIER_OID = + ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA); + + // OIDs from other sources which show up in X.500 names we + // expect to deal with often. + // + // OID for "IP=" IP address attributes, used with SKIP. + public static final ObjectIdentifier ipAddress_oid = + ObjectIdentifier.newInternal(ipAddress_data); + + // Domain component OID from RFC 1274, RFC 2247, RFC 5280. + // + // OID for "DC=" domain component attributes, used with DNSNames in DN + // format. + public static final ObjectIdentifier DOMAIN_COMPONENT_OID = + ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA); + + // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. + public static final ObjectIdentifier userid_oid = + ObjectIdentifier.newInternal(userid_data); /** * Return constraint type:

      diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CertInfo.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CertInfo.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CertInfo.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CertInfo.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -708,7 +708,7 @@ } /* - * Verify if X.509 V3 Certificate is compliant with RFC 3280. + * Verify if X.509 V3 Certificate is compliant with RFC 5280. */ private void verifyCert(X500Name subject, CertificateExtensions extensions) diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CRLImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CRLImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CRLImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/classes/sun/security/x509/X509CRLImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * 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 @@ * signature BIT STRING } * * More information can be found in - * RFC 3280: Internet X.509 + * RFC 5280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile. *

      * The ASN.1 definition of tbsCertList is: Binary files /tmp/tmpvUNVAr/OQpkqqeEu8/openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/cacerts and /tmp/tmpvUNVAr/grBshwB91D/openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/cacerts differ diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-aix openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-aix --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-aix 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-aix 2020-01-15 20:05:09.000000000 +0000 @@ -341,7 +341,7 @@ # By default, the location of the OCSP responder is determined implicitly # from the certificate being validated. This property explicitly specifies # the location of the OCSP responder. The property is used when the -# Authority Information Access extension (defined in RFC 3280) is absent +# Authority Information Access extension (defined in RFC 5280) is absent # from the certificate or when it requires overriding. # # Example, @@ -420,6 +420,32 @@ # krb5.kdc.bad.policy = tryLess:2,2000 krb5.kdc.bad.policy = tryLast +# +# Kerberos cross-realm referrals (RFC 6806) +# +# OpenJDK's Kerberos client supports cross-realm referrals as defined in +# RFC 6806. This allows to setup more dynamic environments in which clients +# do not need to know in advance how to reach the realm of a target principal +# (either a user or service). +# +# When a client issues an AS or a TGS request, the "canonicalize" option +# is set to announce support of this feature. A KDC server may fulfill the +# request or reply referring the client to a different one. If referred, +# the client will issue a new request and the cycle repeats. +# +# In addition to referrals, the "canonicalize" option allows the KDC server +# to change the client name in response to an AS request. For security reasons, +# RFC 6806 (section 11) FAST scheme is enforced. +# +# Disable Kerberos cross-realm referrals. Value may be overwritten with a +# System property (-Dsun.security.krb5.disableReferrals). +sun.security.krb5.disableReferrals=false + +# Maximum number of AS or TGS referrals to avoid infinite loops. Value may +# be overwritten with a System property (-Dsun.security.krb5.maxReferrals). +sun.security.krb5.maxReferrals=5 + +# # Algorithm restrictions for certification path (CertPath) processing # # In some environments, certain algorithms or key lengths may be undesirable @@ -860,8 +886,8 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # -# If the system property jdk.serialFilter is also specified, it supersedes -# the security property value defined here. +# If the system property jdk.serialFilter is also specified on the command +# line, it supersedes the security property value defined here. # # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-linux openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-linux --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-linux 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-linux 2020-01-15 20:05:09.000000000 +0000 @@ -341,7 +341,7 @@ # By default, the location of the OCSP responder is determined implicitly # from the certificate being validated. This property explicitly specifies # the location of the OCSP responder. The property is used when the -# Authority Information Access extension (defined in RFC 3280) is absent +# Authority Information Access extension (defined in RFC 5280) is absent # from the certificate or when it requires overriding. # # Example, @@ -420,6 +420,32 @@ # krb5.kdc.bad.policy = tryLess:2,2000 krb5.kdc.bad.policy = tryLast +# +# Kerberos cross-realm referrals (RFC 6806) +# +# OpenJDK's Kerberos client supports cross-realm referrals as defined in +# RFC 6806. This allows to setup more dynamic environments in which clients +# do not need to know in advance how to reach the realm of a target principal +# (either a user or service). +# +# When a client issues an AS or a TGS request, the "canonicalize" option +# is set to announce support of this feature. A KDC server may fulfill the +# request or reply referring the client to a different one. If referred, +# the client will issue a new request and the cycle repeats. +# +# In addition to referrals, the "canonicalize" option allows the KDC server +# to change the client name in response to an AS request. For security reasons, +# RFC 6806 (section 11) FAST scheme is enforced. +# +# Disable Kerberos cross-realm referrals. Value may be overwritten with a +# System property (-Dsun.security.krb5.disableReferrals). +sun.security.krb5.disableReferrals=false + +# Maximum number of AS or TGS referrals to avoid infinite loops. Value may +# be overwritten with a System property (-Dsun.security.krb5.maxReferrals). +sun.security.krb5.maxReferrals=5 + +# # Algorithm restrictions for certification path (CertPath) processing # # In some environments, certain algorithms or key lengths may be undesirable @@ -861,8 +887,8 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # -# If the system property jdk.serialFilter is also specified, it supersedes -# the security property value defined here. +# If the system property jdk.serialFilter is also specified on the command +# line, it supersedes the security property value defined here. # # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-macosx openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-macosx --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-macosx 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-macosx 2020-01-15 20:05:09.000000000 +0000 @@ -344,7 +344,7 @@ # By default, the location of the OCSP responder is determined implicitly # from the certificate being validated. This property explicitly specifies # the location of the OCSP responder. The property is used when the -# Authority Information Access extension (defined in RFC 3280) is absent +# Authority Information Access extension (defined in RFC 5280) is absent # from the certificate or when it requires overriding. # # Example, @@ -423,6 +423,32 @@ # krb5.kdc.bad.policy = tryLess:2,2000 krb5.kdc.bad.policy = tryLast +# +# Kerberos cross-realm referrals (RFC 6806) +# +# OpenJDK's Kerberos client supports cross-realm referrals as defined in +# RFC 6806. This allows to setup more dynamic environments in which clients +# do not need to know in advance how to reach the realm of a target principal +# (either a user or service). +# +# When a client issues an AS or a TGS request, the "canonicalize" option +# is set to announce support of this feature. A KDC server may fulfill the +# request or reply referring the client to a different one. If referred, +# the client will issue a new request and the cycle repeats. +# +# In addition to referrals, the "canonicalize" option allows the KDC server +# to change the client name in response to an AS request. For security reasons, +# RFC 6806 (section 11) FAST scheme is enforced. +# +# Disable Kerberos cross-realm referrals. Value may be overwritten with a +# System property (-Dsun.security.krb5.disableReferrals). +sun.security.krb5.disableReferrals=false + +# Maximum number of AS or TGS referrals to avoid infinite loops. Value may +# be overwritten with a System property (-Dsun.security.krb5.maxReferrals). +sun.security.krb5.maxReferrals=5 + +# # Algorithm restrictions for certification path (CertPath) processing # # In some environments, certain algorithms or key lengths may be undesirable @@ -864,8 +890,8 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # -# If the system property jdk.serialFilter is also specified, it supersedes -# the security property value defined here. +# If the system property jdk.serialFilter is also specified on the command +# line, it supersedes the security property value defined here. # # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-solaris openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-solaris --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-solaris 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-solaris 2020-01-15 20:05:09.000000000 +0000 @@ -343,7 +343,7 @@ # By default, the location of the OCSP responder is determined implicitly # from the certificate being validated. This property explicitly specifies # the location of the OCSP responder. The property is used when the -# Authority Information Access extension (defined in RFC 3280) is absent +# Authority Information Access extension (defined in RFC 5280) is absent # from the certificate or when it requires overriding. # # Example, @@ -422,6 +422,32 @@ # krb5.kdc.bad.policy = tryLess:2,2000 krb5.kdc.bad.policy = tryLast +# +# Kerberos cross-realm referrals (RFC 6806) +# +# OpenJDK's Kerberos client supports cross-realm referrals as defined in +# RFC 6806. This allows to setup more dynamic environments in which clients +# do not need to know in advance how to reach the realm of a target principal +# (either a user or service). +# +# When a client issues an AS or a TGS request, the "canonicalize" option +# is set to announce support of this feature. A KDC server may fulfill the +# request or reply referring the client to a different one. If referred, +# the client will issue a new request and the cycle repeats. +# +# In addition to referrals, the "canonicalize" option allows the KDC server +# to change the client name in response to an AS request. For security reasons, +# RFC 6806 (section 11) FAST scheme is enforced. +# +# Disable Kerberos cross-realm referrals. Value may be overwritten with a +# System property (-Dsun.security.krb5.disableReferrals). +sun.security.krb5.disableReferrals=false + +# Maximum number of AS or TGS referrals to avoid infinite loops. Value may +# be overwritten with a System property (-Dsun.security.krb5.maxReferrals). +sun.security.krb5.maxReferrals=5 + +# # Algorithm restrictions for certification path (CertPath) processing # # In some environments, certain algorithms or key lengths may be undesirable @@ -863,8 +889,8 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # -# If the system property jdk.serialFilter is also specified, it supersedes -# the security property value defined here. +# If the system property jdk.serialFilter is also specified on the command +# line, it supersedes the security property value defined here. # # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-windows openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-windows --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/lib/security/java.security-windows 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/lib/security/java.security-windows 2020-01-15 20:05:09.000000000 +0000 @@ -344,7 +344,7 @@ # By default, the location of the OCSP responder is determined implicitly # from the certificate being validated. This property explicitly specifies # the location of the OCSP responder. The property is used when the -# Authority Information Access extension (defined in RFC 3280) is absent +# Authority Information Access extension (defined in RFC 5280) is absent # from the certificate or when it requires overriding. # # Example, @@ -423,6 +423,32 @@ # krb5.kdc.bad.policy = tryLess:2,2000 krb5.kdc.bad.policy = tryLast +# +# Kerberos cross-realm referrals (RFC 6806) +# +# OpenJDK's Kerberos client supports cross-realm referrals as defined in +# RFC 6806. This allows to setup more dynamic environments in which clients +# do not need to know in advance how to reach the realm of a target principal +# (either a user or service). +# +# When a client issues an AS or a TGS request, the "canonicalize" option +# is set to announce support of this feature. A KDC server may fulfill the +# request or reply referring the client to a different one. If referred, +# the client will issue a new request and the cycle repeats. +# +# In addition to referrals, the "canonicalize" option allows the KDC server +# to change the client name in response to an AS request. For security reasons, +# RFC 6806 (section 11) FAST scheme is enforced. +# +# Disable Kerberos cross-realm referrals. Value may be overwritten with a +# System property (-Dsun.security.krb5.disableReferrals). +sun.security.krb5.disableReferrals=false + +# Maximum number of AS or TGS referrals to avoid infinite loops. Value may +# be overwritten with a System property (-Dsun.security.krb5.maxReferrals). +sun.security.krb5.maxReferrals=5 + +# # Algorithm restrictions for certification path (CertPath) processing # # In some environments, certain algorithms or key lengths may be undesirable @@ -864,8 +890,8 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # -# If the system property jdk.serialFilter is also specified, it supersedes -# the security property value defined here. +# If the system property jdk.serialFilter is also specified on the command +# line, it supersedes the security property value defined here. # # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/font/freetypeScaler.c openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/font/freetypeScaler.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/font/freetypeScaler.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/font/freetypeScaler.c 2020-01-15 20:05:09.000000000 +0000 @@ -41,6 +41,7 @@ #include FT_SIZES_H #include FT_OUTLINE_H #include FT_SYNTHESIS_H +#include FT_LCD_FILTER_H #include FT_MODULE_H #include "fontscaler.h" @@ -490,6 +491,8 @@ if (errCode == 0) { errCode = FT_Activate_Size(scalerInfo->face->size); } + + FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT); } return errCode; @@ -559,6 +562,14 @@ /* See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657854 */ #define FT_MulFixFloatShift6(a, b) (((float) (a)) * ((float) (b)) / 65536.0 / 64.0) +#define contextAwareMetricsX(x, y) \ + (FTFixedToFloat(context->transform.xx) * (x) - \ + FTFixedToFloat(context->transform.xy) * (y)) + +#define contextAwareMetricsY(x, y) \ + (-FTFixedToFloat(context->transform.yx) * (x) + \ + FTFixedToFloat(context->transform.yy) * (y)) + /* * See FreeType source code: src/base/ftobjs.c ft_recompute_scaled_metrics() * http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1659 @@ -591,9 +602,13 @@ my = 0; metrics = (*env)->NewObject(env, - sunFontIDs.strikeMetricsClass, - sunFontIDs.strikeMetricsCtr, - ax, ay, dx, dy, bx, by, lx, ly, mx, my); + sunFontIDs.strikeMetricsClass, + sunFontIDs.strikeMetricsCtr, + contextAwareMetricsX(ax, ay), contextAwareMetricsY(ax, ay), + contextAwareMetricsX(dx, dy), contextAwareMetricsY(dx, dy), + bx, by, + contextAwareMetricsX(lx, ly), contextAwareMetricsY(lx, ly), + contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my)); return metrics; } @@ -660,10 +675,14 @@ pScalerContext, pScaler, glyphCode); info = (GlyphInfo*) jlong_to_ptr(image); - (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX); - (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY); - - free(info); + if (info != NULL) { + (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX); + (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY); + free(info); + } else { + (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, 0.0f); + (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, 0.0f); + } } @@ -1198,86 +1217,60 @@ return 1; } -static void addToGP(GPData* gpdata, FT_Outline*outline) { - jbyte current_type=SEG_UNKNOWN; - int i, j; - jfloat x, y; +static void addSeg(GPData *gp, jbyte type) { + gp->pointTypes[gp->numTypes++] = type; +} - j = 0; - for(i=0; in_points; i++) { - x = F26Dot6ToFloat(outline->points[i].x); - y = -F26Dot6ToFloat(outline->points[i].y); - - if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_ON) { - /* If bit 0 is unset, the point is "off" the curve, - i.e., a Bezier control point, while it is "on" when set. */ - if (current_type == SEG_UNKNOWN) { /* special case: - very first point */ - /* add segment */ - gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO; - current_type = SEG_LINETO; - } else { - gpdata->pointTypes[gpdata->numTypes++] = current_type; - current_type = SEG_LINETO; - } - } else { - if (current_type == SEG_UNKNOWN) { /* special case: - very first point */ - if (FT_CURVE_TAG(outline->tags[i+1]) == FT_CURVE_TAG_ON) { - /* just skip first point. Adhoc heuristic? */ - continue; - } else { - x = (x + F26Dot6ToFloat(outline->points[i+1].x))/2; - y = (y - F26Dot6ToFloat(outline->points[i+1].y))/2; - gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO; - current_type = SEG_LINETO; - } - } else if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_CUBIC) { - /* Bit 1 is meaningful for 'off' points only. - If set, it indicates a third-order Bezier arc control - point; and a second-order control point if unset. */ - current_type = SEG_CUBICTO; - } else { - /* two successive conic "off" points forces the rasterizer - to create (during the scan-line conversion process - exclusively) a virtual "on" point amidst them, at their - exact middle. This greatly facilitates the definition of - successive conic Bezier arcs. Moreover, it is the way - outlines are described in the TrueType specification. */ - if (current_type == SEG_QUADTO) { - gpdata->pointCoords[gpdata->numCoords++] = - F26Dot6ToFloat(outline->points[i].x + - outline->points[i-1].x)/2; - gpdata->pointCoords[gpdata->numCoords++] = - - F26Dot6ToFloat(outline->points[i].y + - outline->points[i-1].y)/2; - gpdata->pointTypes[gpdata->numTypes++] = SEG_QUADTO; - } - current_type = SEG_QUADTO; - } - } - gpdata->pointCoords[gpdata->numCoords++] = x; - gpdata->pointCoords[gpdata->numCoords++] = y; - if (outline->contours[j] == i) { //end of contour - int start = j > 0 ? outline->contours[j-1]+1 : 0; - gpdata->pointTypes[gpdata->numTypes++] = current_type; - if (current_type == SEG_QUADTO && - FT_CURVE_TAG(outline->tags[start]) != FT_CURVE_TAG_ON) { - gpdata->pointCoords[gpdata->numCoords++] = - (F26Dot6ToFloat(outline->points[start].x) + x)/2; - gpdata->pointCoords[gpdata->numCoords++] = - (-F26Dot6ToFloat(outline->points[start].y) + y)/2; - } else { - gpdata->pointCoords[gpdata->numCoords++] = - F26Dot6ToFloat(outline->points[start].x); - gpdata->pointCoords[gpdata->numCoords++] = - -F26Dot6ToFloat(outline->points[start].y); - } - gpdata->pointTypes[gpdata->numTypes++] = SEG_CLOSE; - current_type = SEG_UNKNOWN; - j++; - } - } +static void addCoords(GPData *gp, FT_Vector *p) { + gp->pointCoords[gp->numCoords++] = F26Dot6ToFloat(p->x); + gp->pointCoords[gp->numCoords++] = -F26Dot6ToFloat(p->y); +} + +static int moveTo(FT_Vector *to, GPData *gp) { + if (gp->numCoords) + addSeg(gp, SEG_CLOSE); + addCoords(gp, to); + addSeg(gp, SEG_MOVETO); + return FT_Err_Ok; +} + +static int lineTo(FT_Vector *to, GPData *gp) { + addCoords(gp, to); + addSeg(gp, SEG_LINETO); + return FT_Err_Ok; +} + +static int conicTo(FT_Vector *control, FT_Vector *to, GPData *gp) { + addCoords(gp, control); + addCoords(gp, to); + addSeg(gp, SEG_QUADTO); + return FT_Err_Ok; +} + +static int cubicTo(FT_Vector *control1, + FT_Vector *control2, + FT_Vector *to, + GPData *gp) { + addCoords(gp, control1); + addCoords(gp, control2); + addCoords(gp, to); + addSeg(gp, SEG_CUBICTO); + return FT_Err_Ok; +} + +static void addToGP(GPData* gpdata, FT_Outline*outline) { + static const FT_Outline_Funcs outline_funcs = { + (FT_Outline_MoveToFunc) moveTo, + (FT_Outline_LineToFunc) lineTo, + (FT_Outline_ConicToFunc) conicTo, + (FT_Outline_CubicToFunc) cubicTo, + 0, /* shift */ + 0, /* delta */ + }; + + FT_Outline_Decompose(outline, &outline_funcs, gpdata); + if (gpdata->numCoords) + addSeg(gpdata, SEG_CLOSE); /* If set to 1, the outline will be filled using the even-odd fill rule */ if (outline->flags & FT_OUTLINE_EVEN_ODD_FILL) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/font/layout/MorphTables2.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/font/layout/MorphTables2.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/font/layout/MorphTables2.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/font/layout/MorphTables2.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -192,7 +192,7 @@ for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) { if(subtable>0) { le_uint32 length = SWAPL(subtableHeader->length); - if (length & 0x03) { // incorrect alignment for 32 bit tables + if (length & 0x01) { // incorrect alignment for 32 bit tables success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any return; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.c openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ * The following methods are implemented in the windowing system (i.e. GLX * and WGL) source files. */ -extern jlong OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo); extern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo); extern void OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo); @@ -593,11 +592,14 @@ OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops) { OGLSDOps *oglsdo = (OGLSDOps *)ops; - jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo); + jobject graphicsConfig = oglsdo->graphicsConfig; JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData", - "dispose", "(JJ)V", - ptr_to_jlong(ops), pConfigInfo); + "dispose", + "(JLsun/java2d/opengl/OGLGraphicsConfig;)V", + ptr_to_jlong(ops), graphicsConfig); + (*env)->DeleteGlobalRef(env, graphicsConfig); + oglsdo->graphicsConfig = NULL; } /** diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.h openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.h --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.h 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/java2d/opengl/OGLSurfaceData.h 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,9 @@ * Pointer to native-specific (GLX, WGL, etc.) SurfaceData info, such as the * native Drawable handle and GraphicsConfig data. * + * jobject graphicsConfig;; + * Strong reference to the OGLGraphicsConfig used by this OGLSurfaceData. + * * jint drawableType; * The surface type; can be any one of the surface type constants defined * below (OGLSD_WINDOW, OGLSD_TEXTURE, etc). @@ -162,6 +165,7 @@ struct _OGLSDOps { SurfaceDataOps sdOps; void *privOps; + jobject graphicsConfig; jint drawableType; GLenum activeBuffer; jboolean isOpaque; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/security/krb5/nativeccache.c openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/security/krb5/nativeccache.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/share/native/sun/security/krb5/nativeccache.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/share/native/sun/security/krb5/nativeccache.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -418,7 +418,7 @@ if (krbcredsConstructor == 0) { krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", - "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); + "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n"); break; @@ -432,7 +432,9 @@ krbcredsConstructor, ticket, clientPrincipal, + NULL, targetPrincipal, + NULL, encryptionKey, ticketFlags, authTime, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/java/lang/UNIXProcess.java openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/java/lang/UNIXProcess.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/java/lang/UNIXProcess.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/java/lang/UNIXProcess.java 2020-01-15 20:05:09.000000000 +0000 @@ -408,8 +408,7 @@ long deadline = System.nanoTime() + remainingNanos; do { - // Round up to next millisecond - wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L)); + TimeUnit.NANOSECONDS.timedWait(this, remainingNanos); if (hasExited) { return true; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/sun/awt/X11/XToolkit.java openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/sun/awt/X11/XToolkit.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/sun/awt/X11/XToolkit.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/sun/awt/X11/XToolkit.java 2020-01-15 20:05:09.000000000 +0000 @@ -2415,14 +2415,16 @@ //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd())); break; case XConstants.XkbMapNotify : - //TODO: provide a simple unit test. - XlibWrapper.XkbGetUpdatedMap(getDisplay(), - XConstants.XkbKeyTypesMask | - XConstants.XkbKeySymsMask | - XConstants.XkbModifierMapMask | - XConstants.XkbVirtualModsMask, - awt_XKBDescPtr); - //System.out.println("XkbMap:"+(xke.get_map())); + if (awt_XKBDescPtr != 0) { + //TODO: provide a simple unit test. + XlibWrapper.XkbGetUpdatedMap(getDisplay(), + XConstants.XkbKeyTypesMask | + XConstants.XkbKeySymsMask | + XConstants.XkbModifierMapMask | + XConstants.XkbVirtualModsMask, + awt_XKBDescPtr); + } + //System.out.println("XkbMap:"+(xke.get_map())); break; case XConstants.XkbStateNotify : // May use it later e.g. to obtain an effective group etc. diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java 2020-01-15 20:05:09.000000000 +0000 @@ -41,7 +41,8 @@ protected X11ComponentPeer peer; private GLXGraphicsConfig graphicsConfig; - private native void initOps(X11ComponentPeer peer, long aData); + private native void initOps(OGLGraphicsConfig gc, X11ComponentPeer peer, + long aData); protected native boolean initPbuffer(long pData, long pConfigInfo, boolean isOpaque, int width, int height); @@ -52,7 +53,7 @@ super(gc, cm, type); this.peer = peer; this.graphicsConfig = gc; - initOps(peer, graphicsConfig.getAData()); + initOps(gc, peer, graphicsConfig.getAData()); } public GraphicsConfiguration getDeviceConfiguration() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/java/util/TimeZone_md.c openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/java/util/TimeZone_md.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/java/util/TimeZone_md.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/java/util/TimeZone_md.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ #include "jvm.h" #include "TimeZone_md.h" +static char *isFileIdentical(char* buf, size_t size, char *pathname); + #define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++; #if defined(_ALLBSD_SOURCE) @@ -65,6 +67,8 @@ static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime"; #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */ +static const char popularZones[][4] = {"UTC", "GMT"}; + #if defined(_AIX) static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; #endif @@ -114,14 +118,28 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) { DIR *dirp = NULL; - struct stat statbuf; struct dirent64 *dp = NULL; struct dirent64 *entry = NULL; char *pathname = NULL; - int fd = -1; - char *dbuf = NULL; char *tz = NULL; + if (strcmp(dir, ZONEINFO_DIR) == 0) { + /* fast path for 1st iteration */ + unsigned int i; + for (i = 0; i < sizeof (popularZones) / sizeof (popularZones[0]); i++) { + pathname = getPathName(dir, popularZones[i]); + if (pathname == NULL) { + continue; + } + tz = isFileIdentical(buf, size, pathname); + free((void *) pathname); + pathname = NULL; + if (tz != NULL) { + return tz; + } + } + } + dirp = opendir(dir); if (dirp == NULL) { return NULL; @@ -161,40 +179,14 @@ if (pathname == NULL) { break; } - if (stat(pathname, &statbuf) == -1) { - break; - } - if (S_ISDIR(statbuf.st_mode)) { - tz = findZoneinfoFile(buf, size, pathname); - if (tz != NULL) { - break; - } - } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) { - dbuf = (char *) malloc(size); - if (dbuf == NULL) { - break; - } - if ((fd = open(pathname, O_RDONLY)) == -1) { - break; - } - if (read(fd, dbuf, size) != (ssize_t) size) { - break; - } - if (memcmp(buf, dbuf, size) == 0) { - tz = getZoneName(pathname); - if (tz != NULL) { - tz = strdup(tz); - } - break; - } - free((void *) dbuf); - dbuf = NULL; - (void) close(fd); - fd = -1; - } + tz = isFileIdentical(buf, size, pathname); + free((void *) pathname); pathname = NULL; + if (tz != NULL) { + break; + } } if (entry != NULL) { @@ -203,16 +195,53 @@ if (dirp != NULL) { (void) closedir(dirp); } - if (pathname != NULL) { - free((void *) pathname); - } - if (fd != -1) { - (void) close(fd); + return tz; +} + +/* + * Checks if the file pointed to by pathname matches + * the data contents in buf. + * Returns a representation of the timezone file name + * if file match is found, otherwise NULL. + */ +static char * +isFileIdentical(char *buf, size_t size, char *pathname) +{ + char *possibleMatch = NULL; + struct stat statbuf; + char *dbuf = NULL; + int fd = -1; + int res; + + if (stat(pathname, &statbuf) == -1) { + return NULL; } - if (dbuf != NULL) { + + if (S_ISDIR(statbuf.st_mode)) { + possibleMatch = findZoneinfoFile(buf, size, pathname); + } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) { + dbuf = (char *) malloc(size); + if (dbuf == NULL) { + return NULL; + } + if ((fd = open(pathname, O_RDONLY)) == -1) { + goto freedata; + } + if (read(fd, dbuf, size) != (ssize_t) size) { + goto freedata; + } + if (memcmp(buf, dbuf, size) == 0) { + possibleMatch = getZoneName(pathname); + if (possibleMatch != NULL) { + possibleMatch = strdup(possibleMatch); + } + } + freedata: free((void *) dbuf); + dbuf = NULL; + (void) close(fd); } - return tz; + return possibleMatch; } #if defined(__linux__) || defined(MACOSX) diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/awt/gtk_interface.c openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/awt/gtk_interface.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/awt/gtk_interface.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/awt/gtk_interface.c 2020-01-15 20:05:09.000000000 +0000 @@ -45,18 +45,18 @@ static GtkLib gtk_libs[] = { { - GTK_2, - JNI_LIB_NAME("gtk-x11-2.0"), - VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"), - >k2_load, - >k2_check - }, - { GTK_3, JNI_LIB_NAME("gtk-3"), VERSIONED_JNI_LIB_NAME("gtk-3", "0"), >k3_load, >k3_check + }, + { + GTK_2, + JNI_LIB_NAME("gtk-x11-2.0"), + VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"), + >k2_load, + >k2_check } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,23 +54,32 @@ JNIEXPORT void JNICALL Java_sun_java2d_opengl_GLXSurfaceData_initOps(JNIEnv *env, jobject glxsd, + jobject gc, jobject peer, jlong aData) { #ifndef HEADLESS - GLXSDOps *glxsdo = (GLXSDOps *)malloc(sizeof(GLXSDOps)); - - if (glxsdo == NULL) { - JNU_ThrowOutOfMemoryError(env, "creating native GLX ops"); + gc = (*env)->NewGlobalRef(env, gc); + if (gc == NULL) { + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); return; } OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, glxsd, sizeof(OGLSDOps)); if (oglsdo == NULL) { - free(glxsdo); + (*env)->DeleteGlobalRef(env, gc); JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); return; } + // later the graphicsConfig will be used for deallocation of oglsdo + oglsdo->graphicsConfig = gc; + + GLXSDOps *glxsdo = (GLXSDOps *)malloc(sizeof(GLXSDOps)); + + if (glxsdo == NULL) { + JNU_ThrowOutOfMemoryError(env, "creating native GLX ops"); + return; + } J2dTraceLn(J2D_TRACE_INFO, "GLXSurfaceData_initOps"); @@ -165,39 +174,6 @@ } /** - * Returns a pointer (as a jlong) to the native GLXGraphicsConfigInfo - * associated with the given OGLSDOps. This method can be called from - * shared code to retrieve the native GraphicsConfig data in a platform- - * independent manner. - */ -jlong -OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo) -{ - GLXSDOps *glxsdo; - - if (oglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "OGLSD_GetNativeConfigInfo: ops are null"); - return 0L; - } - - glxsdo = (GLXSDOps *)oglsdo->privOps; - if (glxsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "OGLSD_GetNativeConfigInfo: glx ops are null"); - return 0L; - } - - if (glxsdo->configData == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "OGLSD_GetNativeConfigInfo: config data is null"); - return 0L; - } - - return ptr_to_jlong(glxsdo->configData->glxInfo); -} - -/** * Makes the given GraphicsConfig's context current to its associated * "scratch" surface. If there is a problem making the context current, * this method will return NULL; otherwise, returns a pointer to the diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.c openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.c 2020-01-15 20:05:09.000000000 +0000 @@ -78,6 +78,7 @@ static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo, SurfaceDataBounds *bounds, jint lockFlags); +static int X11SD_GetBitmapPad(int pixelStride); extern jfieldID validID; @@ -438,11 +439,33 @@ xsdo->drawable = drawable; xsdo->isPixmap = JNI_FALSE; } else { + jboolean sizeIsInvalid = JNI_FALSE; + jlong scan = 0; + /* * width , height must be nonzero otherwise XCreatePixmap * generates BadValue in error_handler */ if (width <= 0 || height <= 0 || width > 32767 || height > 32767) { + sizeIsInvalid = JNI_TRUE; + } else { + XImage* tmpImg = NULL; + + AWT_LOCK(); + tmpImg = XCreateImage(awt_display, + xsdo->configData->awt_visInfo.visual, + depth, ZPixmap, 0, NULL, width, height, + X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0); + if (tmpImg) { + scan = (jlong) tmpImg->bytes_per_line; + XDestroyImage(tmpImg); + tmpImg = NULL; + } + AWT_UNLOCK(); + JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); + } + + if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) { JNU_ThrowOutOfMemoryError(env, "Can't create offscreen surface"); return JNI_FALSE; @@ -457,7 +480,7 @@ xsdo->pmHeight = height; #ifdef MITSHM - xsdo->shmPMData.pmSize = width * height * depth; + xsdo->shmPMData.pmSize = (jlong) width * height * depth; xsdo->shmPMData.pixelsReadThreshold = width * height / 8; if (forceSharedPixmaps) { AWT_LOCK(); @@ -560,7 +583,7 @@ return NULL; } shminfo->shmid = - shmget(IPC_PRIVATE, height * img->bytes_per_line, + shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line, IPC_CREAT|mitShmPermissionMask); if (shminfo->shmid < 0) { J2dRlsTraceLn1(J2D_TRACE_ERROR, @@ -622,7 +645,7 @@ XSync(awt_display, False); retImage = cachedXImage; cachedXImage = (XImage *)NULL; - } else if (width * height * xsdo->depth > 0x10000) { + } else if ((jlong) width * height * xsdo->depth > 0x10000) { retImage = X11SD_CreateSharedImage(xsdo, width, height); } return retImage; @@ -978,7 +1001,7 @@ int scan = xpriv->img->bytes_per_line; xpriv->x = x; xpriv->y = y; - pRasInfo->rasBase = xpriv->img->data - x * mult - y * scan; + pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan; pRasInfo->pixelStride = mult; pRasInfo->pixelBitOffset = 0; pRasInfo->scanStride = scan; @@ -1140,8 +1163,8 @@ static void X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) { - int lengthInBytes = img->height * img->bytes_per_line; - int i; + jlong lengthInBytes = (jlong) img->height * img->bytes_per_line; + jlong i; switch (depth) { case 12: @@ -1214,7 +1237,7 @@ Drawable drawable; int depth = xsdo->depth; int mult = xsdo->configData->pixelStride; - int pad = (mult == 3) ? 32 : mult * 8; // pad must be 8, 16, or 32 + int pad = X11SD_GetBitmapPad(mult); jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS; x = bounds->x1; @@ -1280,7 +1303,7 @@ } scan = img->bytes_per_line; - img->data = malloc(h * scan); + img->data = malloc((size_t) h * scan); if (img->data == NULL) { XFree(img); return NULL; @@ -1315,7 +1338,7 @@ int i; img_addr = img->data + - (temp.y1 - y) * scan + (temp.x1 - x) * mult; + (intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult; temp_scan = temp_image->bytes_per_line; temp_addr = temp_image->data; bytes_to_copy = (temp.x2 - temp.x1) * mult; @@ -1349,7 +1372,7 @@ return NULL; } - img->data = malloc(h * img->bytes_per_line); + img->data = malloc((size_t) h * img->bytes_per_line); if (img->data == NULL) { XFree(img); return NULL; @@ -1532,6 +1555,11 @@ #endif /* MITSHM */ } +static int X11SD_GetBitmapPad(int pixelStride) { + // pad must be 8, 16, or 32 + return (pixelStride == 3) ? 32 : pixelStride * 8; +} + #endif /* !HEADLESS */ /* diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.h openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.h --- openjdk-8-8u232-b09/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.h 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/solaris/native/sun/java2d/x11/X11SurfaceData.h 2020-01-15 20:05:09.000000000 +0000 @@ -81,7 +81,7 @@ XShmSegmentInfo *shmSegInfo; /* Shared Memory Segment Info */ jint bytesPerLine; /* needed for ShMem lock */ jboolean xRequestSent; /* true if x request is sent w/o XSync */ - jint pmSize; + jlong pmSize; jboolean usingShmPixmap; Drawable pixmap; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/com/sun/java/accessibility/AccessBridge.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/com/sun/java/accessibility/AccessBridge.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/com/sun/java/accessibility/AccessBridge.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/com/sun/java/accessibility/AccessBridge.java 2020-01-15 20:05:09.000000000 +0000 @@ -102,7 +102,7 @@ // determine which version of the JDK is running String version = getJavaVersionProperty(); - debugString("JDK version = "+version); + debugString("[INFO]:JDK version = "+version); runningOnJDK1_4 = (version.compareTo("1.4") >= 0); runningOnJDK1_5 = (version.compareTo("1.5") >= 0); @@ -129,7 +129,7 @@ Thread abthread = new Thread(new dllRunner()); abthread.setDaemon(true); abthread.start(); - debugString("AccessBridge started"); + debugString("[INFO]:AccessBridge started"); } } @@ -148,7 +148,7 @@ private class shutdownHook implements Runnable { public void run() { - debugString("***** shutdownHook: shutting down..."); + debugString("[INFO]:***** shutdownHook: shutting down..."); javaShutdown(); } } @@ -280,7 +280,7 @@ try { componentParemter[0] = Class.forName("java.awt.Component"); } catch (ClassNotFoundException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } Object[] args = new Object[1]; Component c; @@ -303,15 +303,15 @@ c = (Component) javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args); returnVal = true; } catch (InvocationTargetException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (IllegalAccessException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } } } catch (NoSuchMethodException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (SecurityException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } // verify getComponentFromNativeWindowHandle() method @@ -326,17 +326,17 @@ Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args); returnVal = true; } catch (InvocationTargetException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (IllegalAccessException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (Exception e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } } } catch (NoSuchMethodException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (SecurityException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } } return returnVal; @@ -425,12 +425,12 @@ */ private void saveContextToWindowHandleMapping(AccessibleContext ac, int nativeHandle) { - debugString("saveContextToWindowHandleMapping..."); + debugString("[INFO]:saveContextToWindowHandleMapping..."); if (ac == null) { return; } if (! contextToWindowHandleMap.containsKey(ac)) { - debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle); + debugString("[INFO]: saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle); contextToWindowHandleMap.put(ac, nativeHandle); } } @@ -473,7 +473,7 @@ * returns 0 on error */ private int getNativeWindowHandleFromContext(AccessibleContext ac) { - debugString("getNativeWindowHandleFromContext: ac = "+ac); + debugString("[INFO]: getNativeWindowHandleFromContext: ac = "+ac); try { return contextToWindowHandleMap.get(ac); } catch (Exception ex) { @@ -506,10 +506,10 @@ */ private Component getComponentFromNativeWindowHandle(int nativeHandle) { if (useJAWT_DLL) { - debugString("*** calling jawtGetComponentFromNativeWindowHandle"); + debugString("[INFO]:*** calling jawtGetComponentFromNativeWindowHandle"); return jawtGetComponentFromNativeWindowHandle(nativeHandle); } else { - debugString("*** calling javaGetComponentFromNativeWindowHandle"); + debugString("[INFO]:*** calling javaGetComponentFromNativeWindowHandle"); Object[] args = new Object[1]; if (javaGetComponentFromNativeWindowHandleMethod != null) { try { @@ -527,7 +527,7 @@ } return (Component)o; } catch (InvocationTargetException | IllegalAccessException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } } } @@ -540,11 +540,11 @@ */ private int getNativeWindowHandleFromComponent(final Component target) { if (useJAWT_DLL) { - debugString("*** calling jawtGetNativeWindowHandleFromComponent"); + debugString("[INFO]:*** calling jawtGetNativeWindowHandleFromComponent"); return jawtGetNativeWindowHandleFromComponent(target); } else { Object[] args = new Object[1]; - debugString("*** calling javaGetNativeWindowHandleFromComponent"); + debugString("[INFO]:*** calling javaGetNativeWindowHandleFromComponent"); if (javaGetNativeWindowHandleFromComponentMethod != null) { try { args[0] = target; @@ -559,9 +559,9 @@ contextToWindowHandleMap.put(ac, i); return i.intValue(); } catch (InvocationTargetException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } catch (IllegalAccessException e) { - debugString("Exception: " + e.toString()); + debugString("[ERROR]:Exception: " + e.toString()); } } } @@ -620,8 +620,8 @@ */ private AccessibleContext getAccessibleContextAt_1(final int x, final int y, final AccessibleContext parent) { - debugString(" : getAccessibleContextAt_1 called"); - debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + debugString("[INFO]: getAccessibleContextAt_1 called"); + debugString("[INFO]: -> x = " + x + " y = " + y + " parent = " + parent); if (parent == null) return null; final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable() { @@ -668,8 +668,8 @@ */ private AccessibleContext getAccessibleContextAt_2(final int x, final int y, AccessibleContext parent) { - debugString("getAccessibleContextAt_2 called"); - debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + debugString("[INFO]: getAccessibleContextAt_2 called"); + debugString("[INFO]: -> x = " + x + " y = " + y + " parent = " + parent); return InvocationUtils.invokeAndWait(new Callable() { @Override @@ -678,7 +678,7 @@ if (a != null) { AccessibleContext childAC = a.getAccessibleContext(); if (childAC != null) { - debugString(" returning childAC = " + childAC); + debugString("[INFO]: returning childAC = " + childAC); return childAC; } } @@ -713,7 +713,7 @@ * returns the AccessibleName from an AccessibleContext */ private String getAccessibleNameFromContext(final AccessibleContext ac) { - debugString("***** ac = "+ac.getClass()); + debugString("[INFO]: ***** ac = "+ac.getClass()); if (ac != null) { String s = InvocationUtils.invokeAndWait(new Callable() { @Override @@ -723,13 +723,13 @@ }, ac); if (s != null) { references.increment(s); - debugString("Returning AccessibleName from Context: " + s); + debugString("[INFO]: Returning AccessibleName from Context: " + s); return s; } else { return null; } } else { - debugString("getAccessibleNameFromContext; ac = null!"); + debugString("[INFO]: getAccessibleNameFromContext; ac = null!"); return null; } } @@ -754,7 +754,7 @@ } }, ac); if ( ( null != nameString ) && ( 0 != nameString.length () ) ) { - debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName."); references.increment (nameString); return nameString; } @@ -765,12 +765,12 @@ } }, ac); if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) { - debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription."); references.increment (descriptionString); return descriptionString; } - debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName"); + debugString ("[WARN]: The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName"); /* Step 2: ======= @@ -807,7 +807,7 @@ } if (false == bExtendedSearch) { - debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") ); + debugString ("[INFO]: bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") ); /* Step 3: ======= @@ -840,7 +840,7 @@ }, ac); String text = getAccessibleTextRangeFromContext (ac, 0, charCount); if (null != text) { - debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object."); references.increment (text); return text; } @@ -848,7 +848,7 @@ /* Does the label support the Accessible Icon Interface? */ - debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { @Override public AccessibleIcon[] call() throws Exception { @@ -863,7 +863,7 @@ } }, ac); if (iconDescription != null){ - debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object."); references.increment (iconDescription); return iconDescription; } @@ -885,7 +885,7 @@ } }, ac); final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent); - debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell."); + debugString ("[INFO]: bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell."); if (acTableCell != null) { final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable() { @Override @@ -900,7 +900,7 @@ } }, ac); if (iconDescription != null){ - debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object."); references.increment (iconDescription); return iconDescription; } @@ -914,7 +914,7 @@ /* Does the button support the Accessible Icon Interface? */ - debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { public AccessibleIcon [] call() { return ac.getAccessibleIcon (); @@ -927,7 +927,7 @@ } }, ac); if (iconDescription != null){ - debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object."); references.increment (iconDescription); return iconDescription; } @@ -1007,7 +1007,7 @@ if ( (AccessibleRole.SLIDER == role) && (AccessibleRole.PANEL == parentRole) && (null != parentName) ) { - debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object."); references.increment (parentName); return parentName; } @@ -1024,11 +1024,11 @@ (AccessibleRole.COMBO_BOX == parentRole) ) { bIsEditCombo = true; if (null != parentName) { - debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object."); references.increment (parentName); return parentName; } else if (null != parentDescription) { - debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object."); references.increment (parentDescription); return parentDescription; } @@ -1072,11 +1072,11 @@ String labelName = labelContext.getAccessibleName (); String labelDescription = labelContext.getAccessibleDescription (); if (null != labelName) { - debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case."); references.increment (labelName); return labelName; } else if (null != labelDescription) { - debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case."); references.increment (labelDescription); return labelDescription; } @@ -1085,7 +1085,7 @@ } } } else { - debugString ("bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet."); + debugString ("[ERROR]:bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet."); } //Note: add AccessibleContext to use InvocationUtils.invokeAndWait @@ -1172,7 +1172,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); references.increment (childName); return childName; } @@ -1182,7 +1182,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); references.increment (childDescription); return childDescription; } @@ -1194,7 +1194,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); references.increment (childName); return childName; } @@ -1204,7 +1204,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); references.increment (childDescription); return childDescription; } @@ -1251,7 +1251,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); references.increment (childName); return childName; } @@ -1261,7 +1261,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); references.increment (childDescription); return childDescription; } @@ -1273,7 +1273,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); references.increment (childName); return childName; } @@ -1283,7 +1283,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); references.increment (childDescription); return childDescription; } @@ -1344,7 +1344,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); references.increment (childName); return childName; } @@ -1354,7 +1354,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); references.increment (childDescription); return childDescription; } @@ -1402,7 +1402,7 @@ } }, ac); if ( null != childName ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); references.increment (childName); return childName; } @@ -1412,7 +1412,7 @@ } }, ac); if ( null != childDescription ) { - debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); references.increment (childDescription); return childDescription; } @@ -1425,7 +1425,7 @@ } return null; } else { - debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null."); + debugString ("[ERROR]: AccessBridge::getVirtualAccessibleNameFromContext error - ac == null."); return null; } } @@ -1443,11 +1443,11 @@ }, ac); if (s != null) { references.increment(s); - debugString("Returning AccessibleDescription from Context: " + s); + debugString("[INFO]: Returning AccessibleDescription from Context: " + s); return s; } } else { - debugString("getAccessibleDescriptionFromContext; ac = null"); + debugString("[ERROR]: getAccessibleDescriptionFromContext; ac = null"); } return null; } @@ -1467,12 +1467,12 @@ String s = role.toDisplayString(Locale.US); if (s != null) { references.increment(s); - debugString("Returning AccessibleRole from Context: " + s); + debugString("[INFO]: Returning AccessibleRole from Context: " + s); return s; } } } else { - debugString("getAccessibleRoleStringFromContext; ac = null"); + debugString("[ERROR]: getAccessibleRoleStringFromContext; ac = null"); } return null; } @@ -1511,12 +1511,12 @@ s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US); } references.increment(s); - debugString("Returning AccessibleStateSet from Context: " + s); + debugString("[INFO]: Returning AccessibleStateSet from Context: " + s); return s; } } } else { - debugString("getAccessibleStatesStringFromContext; ac = null"); + debugString("[ERROR]: getAccessibleStatesStringFromContext; ac = null"); } return null; } @@ -1542,11 +1542,11 @@ } } references.increment(s); - debugString("Returning AccessibleStateSet en_US from Context: " + s); + debugString("[INFO]: Returning AccessibleStateSet en_US from Context: " + s); return s; } } - debugString("getAccessibleStatesStringFromContext; ac = null"); + debugString("[ERROR]: getAccessibleStatesStringFromContext; ac = null"); return null; } @@ -1700,11 +1700,11 @@ if (ac != null) { Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); if (r != null) { - debugString(" - Returning Accessible x coord from Context: " + r.x); + debugString("[INFO]: Returning Accessible x coord from Context: " + r.x); return r.x; } } else { - debugString("getAccessibleXcoordFromContext ac = null"); + debugString("[ERROR]: getAccessibleXcoordFromContext ac = null"); } return -1; } @@ -1713,14 +1713,14 @@ * returns the AccessibleComponent y-coord from an AccessibleContext */ private int getAccessibleYcoordFromContext(AccessibleContext ac) { - debugString("getAccessibleYcoordFromContext() called"); + debugString("[INFO]: getAccessibleYcoordFromContext() called"); if (ac != null) { Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); if (r != null) { return r.y; } } else { - debugString("getAccessibleYcoordFromContext; ac = null"); + debugString("[ERROR]: getAccessibleYcoordFromContext; ac = null"); } return -1; } @@ -1735,7 +1735,7 @@ return r.height; } } else { - debugString("getAccessibleHeightFromContext; ac = null"); + debugString("[ERROR]: getAccessibleHeightFromContext; ac = null"); } return -1; } @@ -1750,7 +1750,7 @@ return r.width; } } else { - debugString("getAccessibleWidthFromContext; ac = null"); + debugString("[ERROR]: getAccessibleWidthFromContext; ac = null"); } return -1; } @@ -1765,11 +1765,11 @@ return ac.getAccessibleComponent(); }, ac); if (acmp != null) { - debugString("Returning AccessibleComponent Context"); + debugString("[INFO]: Returning AccessibleComponent Context"); return acmp; } } else { - debugString("getAccessibleComponentFromContext; ac = null"); + debugString("[ERROR]: getAccessibleComponentFromContext; ac = null"); } return null; } @@ -1778,7 +1778,7 @@ * returns the AccessibleAction from an AccessibleContext */ private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) { - debugString("Returning AccessibleAction Context"); + debugString("[INFO]: Returning AccessibleAction Context"); return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { @Override public AccessibleAction call() throws Exception { @@ -1830,7 +1830,7 @@ * XXX */ private Rectangle getCaretLocation(final AccessibleContext ac) { - debugString("getCaretLocation"); + debugString("[INFO]: getCaretLocation"); if (ac==null) return null; return InvocationUtils.invokeAndWait(new Callable() { @@ -1951,7 +1951,7 @@ */ private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac, final int x, final int y) { - debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y); + debugString("[INFO]: getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y); if (ac==null) return -1; return InvocationUtils.invokeAndWait(new Callable() { @@ -2005,7 +2005,7 @@ return s; } } else { - debugString("getAccessibleLetterAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleLetterAtIndexFromContext; ac = null"); } return null; } @@ -2028,7 +2028,7 @@ return s; } } else { - debugString("getAccessibleWordAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleWordAtIndexFromContext; ac = null"); } return null; } @@ -2051,7 +2051,7 @@ return s; } } else { - debugString("getAccessibleSentenceAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleSentenceAtIndexFromContext; ac = null"); } return null; } @@ -2109,7 +2109,7 @@ return s; } } else { - debugString("getAccessibleTextSelectedTextFromContext; ac = null"); + debugString("[ERROR]: getAccessibleTextSelectedTextFromContext; ac = null"); } return null; } @@ -2370,7 +2370,7 @@ return r.x; } } else { - debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleXcoordTextRectAtIndexFromContext; ac = null"); } return -1; } @@ -2385,7 +2385,7 @@ return r.y; } } else { - debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleYcoordTextRectAtIndexFromContext; ac = null"); } return -1; } @@ -2400,7 +2400,7 @@ return r.height; } } else { - debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleHeightTextRectAtIndexFromContext; ac = null"); } return -1; } @@ -2415,7 +2415,7 @@ return r.width; } } else { - debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null"); + debugString("[ERROR]: getAccessibleWidthTextRectAtIndexFromContext; ac = null"); } return -1; } @@ -2429,7 +2429,7 @@ if (as != null) { return StyleConstants.isBold(as); } else { - debugString("getBoldFromAttributeSet; as = null"); + debugString("[ERROR]: getBoldFromAttributeSet; as = null"); } return false; } @@ -2441,7 +2441,7 @@ if (as != null) { return StyleConstants.isItalic(as); } else { - debugString("getItalicFromAttributeSet; as = null"); + debugString("[ERROR]: getItalicFromAttributeSet; as = null"); } return false; } @@ -2453,7 +2453,7 @@ if (as != null) { return StyleConstants.isUnderline(as); } else { - debugString("getUnderlineFromAttributeSet; as = null"); + debugString("[ERROR]: getUnderlineFromAttributeSet; as = null"); } return false; } @@ -2465,7 +2465,7 @@ if (as != null) { return StyleConstants.isStrikeThrough(as); } else { - debugString("getStrikethroughFromAttributeSet; as = null"); + debugString("[ERROR]: getStrikethroughFromAttributeSet; as = null"); } return false; } @@ -2477,7 +2477,7 @@ if (as != null) { return StyleConstants.isSuperscript(as); } else { - debugString("getSuperscriptFromAttributeSet; as = null"); + debugString("[ERROR]: getSuperscriptFromAttributeSet; as = null"); } return false; } @@ -2489,7 +2489,7 @@ if (as != null) { return StyleConstants.isSubscript(as); } else { - debugString("getSubscriptFromAttributeSet; as = null"); + debugString("[ERROR]: getSubscriptFromAttributeSet; as = null"); } return false; } @@ -2505,7 +2505,7 @@ return s; } } else { - debugString("getBackgroundColorFromAttributeSet; as = null"); + debugString("[ERROR]: getBackgroundColorFromAttributeSet; as = null"); } return null; } @@ -2521,7 +2521,7 @@ return s; } } else { - debugString("getForegroundColorFromAttributeSet; as = null"); + debugString("[ERROR]: getForegroundColorFromAttributeSet; as = null"); } return null; } @@ -2537,7 +2537,7 @@ return s; } } else { - debugString("getFontFamilyFromAttributeSet; as = null"); + debugString("[ERROR]: getFontFamilyFromAttributeSet; as = null"); } return null; } @@ -2549,7 +2549,7 @@ if (as != null) { return StyleConstants.getFontSize(as); } else { - debugString("getFontSizeFromAttributeSet; as = null"); + debugString("[ERROR]: getFontSizeFromAttributeSet; as = null"); } return -1; } @@ -2561,7 +2561,7 @@ if (as != null) { return StyleConstants.getAlignment(as); } else { - debugString("getAlignmentFromAttributeSet; as = null"); + debugString("[ERROR]: getAlignmentFromAttributeSet; as = null"); } return -1; } @@ -2573,7 +2573,7 @@ if (as != null) { return StyleConstants.getBidiLevel(as); } else { - debugString("getBidiLevelFromAttributeSet; as = null"); + debugString("[ERROR]: getBidiLevelFromAttributeSet; as = null"); } return -1; } @@ -2586,7 +2586,7 @@ if (as != null) { return StyleConstants.getFirstLineIndent(as); } else { - debugString("getFirstLineIndentFromAttributeSet; as = null"); + debugString("[ERROR]: getFirstLineIndentFromAttributeSet; as = null"); } return -1; } @@ -2598,7 +2598,7 @@ if (as != null) { return StyleConstants.getLeftIndent(as); } else { - debugString("getLeftIndentFromAttributeSet; as = null"); + debugString("[ERROR]: getLeftIndentFromAttributeSet; as = null"); } return -1; } @@ -2610,7 +2610,7 @@ if (as != null) { return StyleConstants.getRightIndent(as); } else { - debugString("getRightIndentFromAttributeSet; as = null"); + debugString("[ERROR]: getRightIndentFromAttributeSet; as = null"); } return -1; } @@ -2622,7 +2622,7 @@ if (as != null) { return StyleConstants.getLineSpacing(as); } else { - debugString("getLineSpacingFromAttributeSet; as = null"); + debugString("[ERROR]: getLineSpacingFromAttributeSet; as = null"); } return -1; } @@ -2634,7 +2634,7 @@ if (as != null) { return StyleConstants.getSpaceAbove(as); } else { - debugString("getSpaceAboveFromAttributeSet; as = null"); + debugString("[ERROR]: getSpaceAboveFromAttributeSet; as = null"); } return -1; } @@ -2646,7 +2646,7 @@ if (as != null) { return StyleConstants.getSpaceBelow(as); } else { - debugString("getSpaceBelowFromAttributeSet; as = null"); + debugString("[ERROR]: getSpaceBelowFromAttributeSet; as = null"); } return -1; } @@ -2795,7 +2795,7 @@ } } } else { - debugString("getCurrentAccessibleValueFromContext; ac = null"); + debugString("[ERROR]: getCurrentAccessibleValueFromContext; ac = null"); } return null; } @@ -2823,7 +2823,7 @@ } } } else { - debugString("getMaximumAccessibleValueFromContext; ac = null"); + debugString("[ERROR]: getMaximumAccessibleValueFromContext; ac = null"); } return null; } @@ -2851,7 +2851,7 @@ } } } else { - debugString("getMinimumAccessibleValueFromContext; ac = null"); + debugString("[ERROR]: getMinimumAccessibleValueFromContext; ac = null"); } return null; } @@ -3038,7 +3038,7 @@ * returns the row count for an AccessibleTable */ private int getAccessibleTableRowCount(final AccessibleContext ac) { - debugString("##### getAccessibleTableRowCount"); + debugString("[INFO]: ##### getAccessibleTableRowCount"); return InvocationUtils.invokeAndWait(new Callable() { @Override public Integer call() throws Exception { @@ -3057,7 +3057,7 @@ * returns the column count for an AccessibleTable */ private int getAccessibleTableColumnCount(final AccessibleContext ac) { - debugString("##### getAccessibleTableColumnCount"); + debugString("[INFO]: ##### getAccessibleTableColumnCount"); return InvocationUtils.invokeAndWait(new Callable() { @Override public Integer call() throws Exception { @@ -3077,7 +3077,7 @@ */ private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at, final int row, final int column) { - debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass()); + debugString("[INFO]: getAccessibleTableCellAccessibleContext: at = "+at.getClass()); if (at == null) return null; return InvocationUtils.invokeAndWait(new Callable() { @Override @@ -3122,7 +3122,7 @@ * returns the index of a cell at a given row and column in an AccessibleTable */ private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) { - debugString("##### getAccessibleTableCellIndex: at="+at); + debugString("[INFO]: ##### getAccessibleTableCellIndex: at="+at); if (at != null) { int cellIndex = row * InvocationUtils.invokeAndWait(new Callable() { @@ -3132,10 +3132,10 @@ } }, getContextFromAccessibleTable(at)) + column; - debugString(" ##### getAccessibleTableCellIndex="+cellIndex); + debugString("[INFO]: ##### getAccessibleTableCellIndex="+cellIndex); return cellIndex; } - debugString(" ##### getAccessibleTableCellIndex FAILED"); + debugString("[ERROR]: ##### getAccessibleTableCellIndex FAILED"); return -1; } @@ -3143,7 +3143,7 @@ * returns the row extent of a cell at a given row and column in an AccessibleTable */ private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) { - debugString("##### getAccessibleTableCellRowExtent"); + debugString("[INFO]: ##### getAccessibleTableCellRowExtent"); if (at != null) { int rowExtent = InvocationUtils.invokeAndWait(new Callable() { @Override @@ -3152,10 +3152,10 @@ } }, getContextFromAccessibleTable(at)); - debugString(" ##### getAccessibleTableCellRowExtent="+rowExtent); + debugString("[INFO]: ##### getAccessibleTableCellRowExtent="+rowExtent); return rowExtent; } - debugString(" ##### getAccessibleTableCellRowExtent FAILED"); + debugString("[ERROR]: ##### getAccessibleTableCellRowExtent FAILED"); return -1; } @@ -3163,7 +3163,7 @@ * returns the column extent of a cell at a given row and column in an AccessibleTable */ private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) { - debugString("##### getAccessibleTableCellColumnExtent"); + debugString("[INFO]: ##### getAccessibleTableCellColumnExtent"); if (at != null) { int columnExtent = InvocationUtils.invokeAndWait(new Callable() { @Override @@ -3172,10 +3172,10 @@ } }, getContextFromAccessibleTable(at)); - debugString(" ##### getAccessibleTableCellColumnExtent="+columnExtent); + debugString("[INFO]: ##### getAccessibleTableCellColumnExtent="+columnExtent); return columnExtent; } - debugString(" ##### getAccessibleTableCellColumnExtent FAILED"); + debugString("[ERROR]: ##### getAccessibleTableCellColumnExtent FAILED"); return -1; } @@ -3184,7 +3184,7 @@ */ private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row, final int column) { - debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]"); + debugString("[INFO]: ##### isAccessibleTableCellSelected: ["+row+"]["+column+"]"); if (at == null) return false; return InvocationUtils.invokeAndWait(new Callable() { @@ -3211,7 +3211,7 @@ * AccessibleTable */ private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) { - debugString(" ##### getAccessibleTableRowHeader called"); + debugString("[INFO]: ##### getAccessibleTableRowHeader called"); AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { @Override public AccessibleTable call() throws Exception { @@ -3235,7 +3235,7 @@ * AccessibleTable */ private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) { - debugString("##### getAccessibleTableColumnHeader"); + debugString("[INFO]: ##### getAccessibleTableColumnHeader"); if (ac == null) return null; AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { @@ -3274,7 +3274,7 @@ */ private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) { - debugString(" ##### getAccessibleTableRowHeaderRowCount called"); + debugString("[INFO]: ##### getAccessibleTableRowHeaderRowCount called"); if (ac != null) { final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); if (atRowHeader != null) { @@ -3297,7 +3297,7 @@ * the row header in an AccessibleTable */ private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) { - debugString(" ##### getAccessibleTableRowHeaderColumnCount called"); + debugString("[INFO]: ##### getAccessibleTableRowHeaderColumnCount called"); if (ac != null) { final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); if (atRowHeader != null) { @@ -3312,7 +3312,7 @@ }, ac); } } - debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED"); + debugString("[ERROR]: ##### getAccessibleTableRowHeaderColumnCount FAILED"); return -1; } @@ -3322,7 +3322,7 @@ */ private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) { - debugString("##### getAccessibleTableColumnHeaderRowCount"); + debugString("[INFO]: ##### getAccessibleTableColumnHeaderRowCount"); if (ac != null) { final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); if (atColumnHeader != null) { @@ -3337,7 +3337,7 @@ }, ac); } } - debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED"); + debugString("[ERROR]: ##### getAccessibleTableColumnHeaderRowCount FAILED"); return -1; } @@ -3347,7 +3347,7 @@ */ private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) { - debugString("##### getAccessibleTableColumnHeaderColumnCount"); + debugString("[ERROR]: ##### getAccessibleTableColumnHeaderColumnCount"); if (ac != null) { final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); if (atColumnHeader != null) { @@ -3362,7 +3362,7 @@ }, ac); } } - debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED"); + debugString("[ERROR]: ##### getAccessibleTableColumnHeaderColumnCount FAILED"); return -1; } @@ -3630,7 +3630,7 @@ */ private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac, final int i, final int j) { - debugString("***** getAccessibleRelationTarget"); + debugString("[INFO]: ***** getAccessibleRelationTarget"); return InvocationUtils.invokeAndWait(new Callable() { @Override public AccessibleContext call() throws Exception { @@ -3663,7 +3663,7 @@ * Returns the AccessibleHypertext */ private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) { - debugString("getAccessibleHyperlink"); + debugString("[INFO]: getAccessibleHyperlink"); if (ac==null) return null; AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable() { @@ -3684,7 +3684,7 @@ * Returns the number of AccessibleHyperlinks */ private int getAccessibleHyperlinkCount(AccessibleContext ac) { - debugString("getAccessibleHyperlinkCount"); + debugString("[INFO]: getAccessibleHyperlinkCount"); if (ac == null) { return 0; } @@ -3705,7 +3705,7 @@ * Returns the hyperlink at the specified index */ private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) { - debugString("getAccessibleHyperlink"); + debugString("[INFO]: getAccessibleHyperlink"); if (hypertext == null) { return null; } @@ -3737,7 +3737,7 @@ * Returns the hyperlink object description */ private String getAccessibleHyperlinkText(final AccessibleHyperlink link) { - debugString("getAccessibleHyperlinkText"); + debugString("[INFO]: getAccessibleHyperlinkText"); if (link == null) { return null; } @@ -3757,7 +3757,7 @@ * Returns the hyperlink URL */ private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) { - debugString("getAccessibleHyperlinkURL"); + debugString("[INFO]: getAccessibleHyperlinkURL"); if (link == null) { return null; } @@ -3778,7 +3778,7 @@ * Returns the start index of the hyperlink text */ private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) { - debugString("getAccessibleHyperlinkStartIndex"); + debugString("[INFO]: getAccessibleHyperlinkStartIndex"); if (link == null) { return -1; } @@ -3794,7 +3794,7 @@ * Returns the end index of the hyperlink text */ private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) { - debugString("getAccessibleHyperlinkEndIndex"); + debugString("[INFO]: getAccessibleHyperlinkEndIndex"); if (link == null) { return -1; } @@ -3812,7 +3812,7 @@ * is no hyperlink associated with this index. */ private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) { - debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex); + debugString("[INFO]: getAccessibleHypertextLinkIndex: charIndex = "+charIndex); if (hypertext == null) { return -1; } @@ -3822,7 +3822,7 @@ return hypertext.getLinkIndex(charIndex); } }, hyperTextContextMap.get(hypertext)); - debugString("getAccessibleHypertextLinkIndex returning "+linkIndex); + debugString("[INFO]: getAccessibleHypertextLinkIndex returning "+linkIndex); return linkIndex; } @@ -3841,7 +3841,7 @@ return link.doAccessibleAction(0); } }, ac); - debugString("activateAccessibleHyperlink: returning = "+retval); + debugString("[INFO]: activateAccessibleHyperlink: returning = "+retval); return retval; } @@ -3969,17 +3969,17 @@ int fKey = fKeyNumber(keyStroke); if (fKey != 0) { // return 0x00000001 through 0x00000018 - debugString(" Shortcut is: F" + fKey); + debugString("[INFO]: Shortcut is: F" + fKey); return (char)fKey; } // If the accelerator is a control character, return it int keyCode = controlCode(keyStroke); if (keyCode != 0) { - debugString(" Shortcut is control character: " + Integer.toHexString(keyCode)); + debugString("[INFO]: Shortcut is control character: " + Integer.toHexString(keyCode)); return (char)keyCode; } String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); - debugString(" Shortcut is: " + keyText); + debugString("[INFO]: Shortcut is: " + keyText); if (keyText != null || keyText.length() > 0) { CharSequence seq = keyText.subSequence(0, 1); if (seq != null || seq.length() > 0) { @@ -3995,7 +3995,7 @@ private int getModifiers(KeyStroke keyStroke) { if (keyStroke == null) return 0; - debugString("In AccessBridge.getModifiers"); + debugString("[INFO]: In AccessBridge.getModifiers"); // modifiers is a bit strip where bits 0-7 indicate a traditional modifier // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates // a control code shortcut such as the delete key. @@ -4022,23 +4022,23 @@ // 0-3 are shift, ctrl, meta, alt // 4-7 are for Solaris workstations (though not being used) if (text.startsWith("met")) { - debugString(" found meta"); + debugString("[INFO]: found meta"); modifiers |= ActionEvent.META_MASK; } if (text.startsWith("ctr")) { - debugString(" found ctrl"); + debugString("[INFO]: found ctrl"); modifiers |= ActionEvent.CTRL_MASK; } if (text.startsWith("alt")) { - debugString(" found alt"); + debugString("[INFO]: found alt"); modifiers |= ActionEvent.ALT_MASK; } if (text.startsWith("shi")) { - debugString(" found shift"); + debugString("[INFO]: found shift"); modifiers |= ActionEvent.SHIFT_MASK; } } - debugString(" returning modifiers: 0x" + Integer.toHexString(modifiers)); + debugString("[INFO]: returning modifiers: 0x" + Integer.toHexString(modifiers)); return modifiers; } @@ -4117,7 +4117,7 @@ * return the number of icons associated with this context */ private int getAccessibleIconsCount(final AccessibleContext ac) { - debugString("getAccessibleIconsCount"); + debugString("[INFO]: getAccessibleIconsCount"); if (ac == null) { return 0; } @@ -4137,7 +4137,7 @@ * return icon description at the specified index */ private String getAccessibleIconDescription(final AccessibleContext ac, final int index) { - debugString("getAccessibleIconDescription: index = "+index); + debugString("[INFO]: getAccessibleIconDescription: index = "+index); if (ac == null) { return null; } @@ -4157,7 +4157,7 @@ * return icon height at the specified index */ private int getAccessibleIconHeight(final AccessibleContext ac, final int index) { - debugString("getAccessibleIconHeight: index = "+index); + debugString("[INFO]: getAccessibleIconHeight: index = "+index); if (ac == null) { return 0; } @@ -4177,7 +4177,7 @@ * return icon width at the specified index */ private int getAccessibleIconWidth(final AccessibleContext ac, final int index) { - debugString("getAccessibleIconWidth: index = "+index); + debugString("[INFO]: getAccessibleIconWidth: index = "+index); if (ac == null) { return 0; } @@ -4199,7 +4199,7 @@ * return the number of icons associated with this context */ private int getAccessibleActionsCount(final AccessibleContext ac) { - debugString("getAccessibleActionsCount"); + debugString("[INFO]: getAccessibleActionsCount"); if (ac == null) { return 0; } @@ -4218,7 +4218,7 @@ * return icon description at the specified index */ private String getAccessibleActionName(final AccessibleContext ac, final int index) { - debugString("getAccessibleActionName: index = "+index); + debugString("[INFO]: getAccessibleActionName: index = "+index); if (ac == null) { return null; } @@ -4237,7 +4237,7 @@ * return icon description at the specified index */ private boolean doAccessibleActions(final AccessibleContext ac, final String name) { - debugString("doAccessibleActions: action name = "+name); + debugString("[INFO]: doAccessibleActions: action name = "+name); if (ac == null || name == null) { return false; } @@ -4275,14 +4275,14 @@ * Returns whether successful. */ private boolean setTextContents(final AccessibleContext ac, final String text) { - debugString("setTextContents: ac = "+ac+"; text = "+text); + debugString("[INFO]: setTextContents: ac = "+ac+"; text = "+text); if (! (ac instanceof AccessibleEditableText)) { - debugString(" ac not instanceof AccessibleEditableText: "+ac); + debugString("[WARN]: ac not instanceof AccessibleEditableText: "+ac); return false; } if (text == null) { - debugString(" text is null"); + debugString("[WARN]: text is null"); return false; } @@ -4319,7 +4319,7 @@ * (AccessibleContext)0 on error. */ private AccessibleContext getTopLevelObject (final AccessibleContext ac) { - debugString("getTopLevelObject; ac = "+ac); + debugString("[INFO]: getTopLevelObject; ac = "+ac); if (ac == null) { return null; } @@ -4356,8 +4356,7 @@ */ private AccessibleContext getParentWithRole (final AccessibleContext ac, final String roleName) { - debugString("getParentWithRole; ac = "+ac); - debugString("role = "+roleName); + debugString("[INFO]: getParentWithRole; ac = "+ac + "\n role = "+roleName); if (ac == null || roleName == null) { return null; } @@ -4413,7 +4412,7 @@ * Returns -1 on error. */ private int getObjectDepth(final AccessibleContext ac) { - debugString("getObjectDepth: ac = "+ac); + debugString("[INFO]: getObjectDepth: ac = "+ac); if (ac == null) { return -1; @@ -4442,7 +4441,7 @@ * Returns (AccessibleContext)0 on error. */ private AccessibleContext getActiveDescendent (final AccessibleContext ac) { - debugString("getActiveDescendent: ac = "+ac); + debugString("[INFO]: getActiveDescendent: ac = "+ac); if (ac == null) { return null; } @@ -4510,7 +4509,7 @@ * Bug ID 4916682 - Implement JAWS AccessibleName policy */ private String getJAWSAccessibleName(final AccessibleContext ac) { - debugString("getJAWSAccessibleName"); + debugString("[INFO]: getJAWSAccessibleName"); if (ac == null) { return null; } @@ -4529,7 +4528,7 @@ * Bug ID 4944757 - requestFocus method needed */ private boolean requestFocus(final AccessibleContext ac) { - debugString("requestFocus"); + debugString("[INFO]: requestFocus"); if (ac == null) { return false; } @@ -4554,7 +4553,7 @@ * Bug ID 4944758 - selectTextRange method needed */ private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) { - debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex); + debugString("[INFO]: selectTextRange: start = "+startIndex+"; end = "+endIndex); if (ac == null) { return false; } @@ -4580,7 +4579,7 @@ * Bug ID 4944770 - setCaretPosition method needed */ private boolean setCaretPosition(final AccessibleContext ac, final int position) { - debugString("setCaretPosition: position = "+position); + debugString("[INFO]: setCaretPosition: position = "+position); if (ac == null) { return false; } @@ -4608,13 +4607,13 @@ private boolean _foundVisibleChild; private int getVisibleChildrenCount(AccessibleContext ac) { - debugString("getVisibleChildrenCount"); + debugString("[INFO]: getVisibleChildrenCount"); if (ac == null) { return -1; } _visibleChildrenCount = 0; _getVisibleChildrenCount(ac); - debugString(" _visibleChildrenCount = "+_visibleChildrenCount); + debugString("[INFO]: _visibleChildrenCount = "+_visibleChildrenCount); return _visibleChildrenCount; } @@ -4754,7 +4753,7 @@ * Bug ID 4944762- getVisibleChildren for list-like components needed */ private AccessibleContext getVisibleChild(AccessibleContext ac, int index) { - debugString("getVisibleChild: index = "+index); + debugString("[INFO]: getVisibleChild: index = "+index); if (ac == null) { return null; } @@ -4764,7 +4763,7 @@ _getVisibleChild(ac, index); if (_visibleChild != null) { - debugString( " getVisibleChild: found child = " + + debugString( "[INFO]: getVisibleChild: found child = " + InvocationUtils.invokeAndWait(new Callable() { @Override public String call() throws Exception { @@ -4953,7 +4952,7 @@ */ void increment(Object o) { if (o == null){ - debugString("ObjectReferences::increment - Passed in object is null"); + debugString("[WARN]: ObjectReferences::increment - Passed in object is null"); return; } @@ -4974,10 +4973,10 @@ if (aRef.value == 0) { refs.remove(o); } else if (aRef.value < 0) { - debugString("ERROR: decrementing reference count below 0"); + debugString("[ERROR]: decrementing reference count below 0"); } } else { - debugString("ERROR: object to decrement not in ObjectReferences table"); + debugString("[ERROR]: object to decrement not in ObjectReferences table"); } } @@ -5312,7 +5311,7 @@ // This is invoked on the EDT , as public void propertyChange(PropertyChangeEvent e) { - accessBridge.debugString("propertyChange(" + e.toString() + ") called"); + accessBridge.debugString("[INFO]: propertyChange(" + e.toString() + ") called"); if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) { Object o = e.getSource(); @@ -5330,7 +5329,7 @@ if (ac != null) { InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext()); - accessBridge.debugString("AccessibleContext: " + ac); + accessBridge.debugString("[INFO]: AccessibleContext: " + ac); String propertyName = e.getPropertyName(); if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) { @@ -5343,8 +5342,7 @@ if (e.getNewValue() instanceof Integer) { newValue = ((Integer) e.getNewValue()).intValue(); } - accessBridge.debugString(" - about to call propertyCaretChange()"); - accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.debugString("[INFO]: - about to call propertyCaretChange() old value: " + oldValue + "new value: " + newValue); accessBridge.propertyCaretChange(e, ac, oldValue, newValue); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) { @@ -5357,8 +5355,7 @@ if (e.getNewValue() != null) { newValue = e.getNewValue().toString(); } - accessBridge.debugString(" - about to call propertyDescriptionChange()"); - accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.debugString("[INFO]: - about to call propertyDescriptionChange() old value: " + oldValue + "new value: " + newValue); accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) { @@ -5371,12 +5368,11 @@ if (e.getNewValue() != null) { newValue = e.getNewValue().toString(); } - accessBridge.debugString(" - about to call propertyNameChange()"); - accessBridge.debugString(" old value: " + oldValue + " new value: " + newValue); + accessBridge.debugString("[INFO]: - about to call propertyNameChange() old value: " + oldValue + " new value: " + newValue); accessBridge.propertyNameChange(e, ac, oldValue, newValue); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) { - accessBridge.debugString(" - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource()); + accessBridge.debugString("[INFO]: - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource()); accessBridge.propertySelectionChange(e, ac); @@ -5394,11 +5390,11 @@ newValue = newState.toDisplayString(Locale.US); } - accessBridge.debugString(" - about to call propertyStateChange()"); + accessBridge.debugString("[INFO]: - about to call propertyStateChange()"); accessBridge.propertyStateChange(e, ac, oldValue, newValue); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) { - accessBridge.debugString(" - about to call propertyTextChange()"); + accessBridge.debugString("[INFO]: - about to call propertyTextChange()"); accessBridge.propertyTextChange(e, ac); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) { // strings 'cause of floating point, etc. @@ -5411,7 +5407,7 @@ if (e.getNewValue() != null) { newValue = e.getNewValue().toString(); } - accessBridge.debugString(" - about to call propertyDescriptionChange()"); + accessBridge.debugString("[INFO]: - about to call propertyDescriptionChange()"); accessBridge.propertyValueChange(e, ac, oldValue, newValue); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) { @@ -5430,8 +5426,7 @@ newAC = (AccessibleContext) e.getNewValue(); InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); } - accessBridge.debugString(" - about to call propertyChildChange()"); - accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); + accessBridge.debugString("[INFO]: - about to call propertyChildChange() old AC: " + oldAC + "new AC: " + newAC); accessBridge.propertyChildChange(e, ac, oldAC, newAC); } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) { @@ -5494,10 +5489,7 @@ } prevAC = newAC; - accessBridge.debugString(" - about to call propertyActiveDescendentChange()"); - accessBridge.debugString(" AC: " + ac); - accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); - + accessBridge.debugString("[INFO]: - about to call propertyActiveDescendentChange() AC: " + ac + " old AC: " + oldAC + "new AC: " + newAC); InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext()); InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC); @@ -5553,10 +5545,9 @@ // This is a popup with an item selected FocusEvent e = new FocusEvent(last, FocusEvent.FOCUS_GAINED); - accessBridge.debugString(" - about to call focusGained()"); AccessibleContext focusedAC = last.getAccessibleContext(); InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last)); - accessBridge.debugString(" AC: " + focusedAC); + accessBridge.debugString("[INFO]: - about to call focusGained() AC: " + focusedAC); accessBridge.focusGained(e, focusedAC); } } @@ -5565,10 +5556,9 @@ if (focusOwner instanceof Accessible) { FocusEvent e = new FocusEvent(focusOwner, FocusEvent.FOCUS_GAINED); - accessBridge.debugString(" - about to call focusGained()"); AccessibleContext focusedAC = focusOwner.getAccessibleContext(); InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner)); - accessBridge.debugString(" AC: " + focusedAC); + accessBridge.debugString("[INFO]: - about to call focusGained() AC: " + focusedAC); accessBridge.focusGained(e, focusedAC); } } @@ -5578,8 +5568,7 @@ if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) { Accessible a = Translator.getAccessible(e.getSource()); if (a != null) { - accessBridge.debugString(" - about to call focusLost()"); - accessBridge.debugString(" AC: " + a.getAccessibleContext()); + accessBridge.debugString("[INFO]: - about to call focusLost() AC: " + a.getAccessibleContext()); AccessibleContext context = a.getAccessibleContext(); InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); accessBridge.focusLost(e, context); @@ -6282,7 +6271,7 @@ isLeaf = treeModel.isLeaf(obj); } } - debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap); + debugString("[INFO]: AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap); } private TreePath getChildTreePath(int i) { @@ -6322,14 +6311,14 @@ } private Component getCurrentComponent() { - debugString("AccessibleJTreeNode: getCurrentComponent"); + debugString("[INFO]: AccessibleJTreeNode: getCurrentComponent"); // is the object visible? // if so, get row, selected, focus & leaf state, // and then get the renderer component and return it if (tree != null && tree.isVisible(path)) { TreeCellRenderer r = tree.getCellRenderer(); if (r == null) { - debugString(" returning null 1"); + debugString("[WARN]: returning null 1"); return null; } TreeUI ui = tree.getUI(); @@ -6341,11 +6330,11 @@ Component retval = r.getTreeCellRendererComponent(tree, obj, selected, expanded, isLeaf, row, hasFocus); - debugString(" returning = "+retval.getClass()); + debugString("[INFO]: returning = "+retval.getClass()); return retval; } } - debugString(" returning null 2"); + debugString("[WARN]: returning null 2"); return null; } @@ -6358,13 +6347,13 @@ * object does not have a name */ public String getAccessibleName() { - debugString("AccessibleJTreeNode: getAccessibleName"); + debugString("[INFO]: AccessibleJTreeNode: getAccessibleName"); AccessibleContext ac = getCurrentAccessibleContext(); if (ac != null) { String name = ac.getAccessibleName(); if ((name != null) && (!name.isEmpty())) { String retval = ac.getAccessibleName(); - debugString(" returning "+retval); + debugString("[INFO]: returning "+retval); return retval; } else { return null; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/java/lang/ProcessImpl.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/java/lang/ProcessImpl.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/java/lang/ProcessImpl.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/java/lang/ProcessImpl.java 2020-01-15 20:05:09.000000000 +0000 @@ -520,11 +520,15 @@ if (timeout <= 0) return false; long remainingNanos = unit.toNanos(timeout); - long deadline = System.nanoTime() + remainingNanos ; + long deadline = System.nanoTime() + remainingNanos; do { // Round up to next millisecond long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L); + if (msTimeout < 0) { + // if wraps around then wait a long while + msTimeout = Integer.MAX_VALUE; + } waitForTimeoutInterruptibly(handle, msTimeout); if (Thread.interrupted()) throw new InterruptedException(); @@ -538,7 +542,7 @@ } private static native void waitForTimeoutInterruptibly( - long handle, long timeout); + long handle, long timeoutMillis); public void destroy() { terminateProcess(handle); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package sun.awt.shell; -import java.awt.*; +import java.awt.Image; +import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.File; @@ -33,14 +34,29 @@ import java.io.IOException; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; -import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; import sun.misc.ThreadGroupUtils; +import sun.util.logging.PlatformLogger; + +import static sun.awt.shell.Win32ShellFolder2.DESKTOP; +import static sun.awt.shell.Win32ShellFolder2.DRIVES; +import static sun.awt.shell.Win32ShellFolder2.Invoker; +import static sun.awt.shell.Win32ShellFolder2.NETWORK; +import static sun.awt.shell.Win32ShellFolder2.PERSONAL; +import static sun.awt.shell.Win32ShellFolder2.RECENT; // NOTE: This class supersedes Win32ShellFolderManager, which was removed // from distribution after version 1.4.2. @@ -54,6 +70,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { + private static final PlatformLogger + log = PlatformLogger.getLogger("sun.awt.shell.Win32ShellFolderManager2"); + static { // Load library here sun.awt.windows.WToolkit.loadLibraries(); @@ -137,12 +156,13 @@ if (desktop == null) { try { desktop = new Win32ShellFolder2(DESKTOP); - } catch (SecurityException e) { - // Ignore error - } catch (IOException e) { - // Ignore error - } catch (InterruptedException e) { - // Ignore error + } catch (final SecurityException ignored) { + // Ignore, the message may have sensitive information, not + // accessible other ways + } catch (IOException | InterruptedException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot access 'Desktop'", e); + } } } return desktop; @@ -152,12 +172,13 @@ if (drives == null) { try { drives = new Win32ShellFolder2(DRIVES); - } catch (SecurityException e) { - // Ignore error - } catch (IOException e) { - // Ignore error - } catch (InterruptedException e) { - // Ignore error + } catch (final SecurityException ignored) { + // Ignore, the message may have sensitive information, not + // accessible other ways + } catch (IOException | InterruptedException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot access 'Drives'", e); + } } } return drives; @@ -170,12 +191,13 @@ if (path != null) { recent = createShellFolder(getDesktop(), new File(path)); } - } catch (SecurityException e) { - // Ignore error - } catch (InterruptedException e) { - // Ignore error - } catch (IOException e) { - // Ignore error + } catch (final SecurityException ignored) { + // Ignore, the message may have sensitive information, not + // accessible other ways + } catch (InterruptedException | IOException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot access 'Recent'", e); + } } } return recent; @@ -185,12 +207,13 @@ if (network == null) { try { network = new Win32ShellFolder2(NETWORK); - } catch (SecurityException e) { - // Ignore error - } catch (IOException e) { - // Ignore error - } catch (InterruptedException e) { - // Ignore error + } catch (final SecurityException ignored) { + // Ignore, the message may have sensitive information, not + // accessible other ways + } catch (IOException | InterruptedException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot access 'Network'", e); + } } } return network; @@ -210,12 +233,13 @@ personal.setIsPersonal(); } } - } catch (SecurityException e) { - // Ignore error - } catch (InterruptedException e) { - // Ignore error - } catch (IOException e) { - // Ignore error + } catch (final SecurityException ignored) { + // Ignore, the message may have sensitive information, not + // accessible other ways + } catch (InterruptedException | IOException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot access 'Personal'", e); + } } } return personal; @@ -316,8 +340,14 @@ folders.add(createShellFolder(new File((String)value))); } } catch (IOException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot read value = " + value, e); + } // Skip this value } catch (InterruptedException e) { + if (log.isLoggable(PlatformLogger.Level.WARNING)) { + log.warning("Cannot read value = " + value, e); + } // Return empty result return new File[0]; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java 2020-01-15 20:05:09.000000000 +0000 @@ -41,8 +41,8 @@ protected WComponentPeer peer; private WGLGraphicsConfig graphicsConfig; - private native void initOps(long pConfigInfo, WComponentPeer peer, - long hwnd); + private native void initOps(OGLGraphicsConfig gc, long pConfigInfo, + WComponentPeer peer, long hwnd); protected native boolean initPbuffer(long pData, long pConfigInfo, boolean isOpaque, int width, int height); @@ -57,7 +57,7 @@ long pConfigInfo = gc.getNativeConfigInfo(); long hwnd = peer != null ? peer.getHWnd() : 0L; - initOps(pConfigInfo, peer, hwnd); + initOps(gc, pConfigInfo, peer, hwnd); } public GraphicsConfiguration getDeviceConfiguration() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java 2020-01-15 20:05:09.000000000 +0000 @@ -36,7 +36,6 @@ import sun.security.krb5.internal.ccache.*; import java.io.IOException; import java.util.Arrays; -import javax.security.auth.kerberos.KerberosPrincipal; import sun.security.util.Password; import javax.security.auth.kerberos.KeyTab; @@ -53,22 +52,9 @@ /** * The main method is used to accept user command line input for ticket - * request. - *

      - * Usage: kinit [-A] [-f] [-p] [-c cachename] [[-k [-t keytab_file_name]] - * [principal] [password] - *

        - *
      • -A do not include addresses - *
      • -f forwardable - *
      • -p proxiable - *
      • -c cache name (i.e., FILE://c:\temp\mykrb5cc) - *
      • -k use keytab - *
      • -t keytab file name - *
      • principal the principal name (i.e., duke@java.sun.com) - *
      • password the principal's Kerberos password - *
      - *

      - * Use java sun.security.krb5.tools.Kinit -help to bring up help menu. + * request. Read {@link KinitOptions#printHelp} for usages or call + * java sun.security.krb5.internal.tools.Kinit -help + * to bring up help menu. *

      * We currently support only file-based credentials cache to * store the tickets obtained from the KDC. @@ -146,6 +132,49 @@ } else { options = new KinitOptions(args); } + switch (options.action) { + case 1: + acquire(); + break; + case 2: + renew(); + break; + default: + throw new KrbException("kinit does not support action " + + options.action); + } + } + + private void renew() + throws IOException, RealmException, KrbException { + + PrincipalName principal = options.getPrincipal(); + String realm = principal.getRealmAsString(); + CredentialsCache cache = CredentialsCache.getInstance(options.cachename); + + if (cache == null) { + throw new IOException("Unable to find existing cache file " + + options.cachename); + } + sun.security.krb5.internal.ccache.Credentials credentials = + cache.getCreds(PrincipalName.tgsService(realm, realm)); + + credentials = credentials.setKrbCreds() + .renew() + .toCCacheCreds(); + + cache = CredentialsCache.create(principal, options.cachename); + if (cache == null) { + throw new IOException("Unable to create the cache file " + + options.cachename); + } + cache.update(credentials); + cache.save(); + } + + private void acquire() + throws IOException, RealmException, KrbException { + String princName = null; PrincipalName principal = options.getPrincipal(); if (principal != null) { @@ -216,6 +245,9 @@ if (options.getAddressOption()) builder.setAddresses(HostAddresses.getLocalAddresses()); + builder.setTill(options.lifetime); + builder.setRTime(options.renewable_lifetime); + builder.action(); sun.security.krb5.internal.ccache.Credentials credentials = diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java 2020-01-15 20:05:09.000000000 +0000 @@ -33,12 +33,8 @@ import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.*; -import java.io.File; import java.io.IOException; -import java.util.StringTokenizer; -import java.util.Vector; -import java.io.BufferedReader; -import java.io.InputStreamReader; +import java.time.Instant; import java.io.FileInputStream; /** @@ -49,14 +45,15 @@ * @author Ram Marti */ class KinitOptions { - public boolean validate = false; + + // 1. acquire, 2. renew, 3. validate + public int action = 1; // forwardable and proxiable flags have two states: // -1 - flag set to be not forwardable or proxiable; // 1 - flag set to be forwardable or proxiable. - public short forwardable = -1; - public short proxiable = -1; - public boolean renew = false; + public short forwardable = 0; + public short proxiable = 0; public KerberosTime lifetime; public KerberosTime renewable_lifetime; public String target_service; @@ -134,6 +131,12 @@ } useKeytab = true; + } else if (args[i].equals("-R")) { + action = 2; + } else if (args[i].equals("-l")) { + lifetime = getTime(Config.duration(args[++i])); + } else if (args[i].equals("-r")) { + renewable_lifetime = getTime(Config.duration(args[++i])); } else if (args[i].equalsIgnoreCase("-help")) { printHelp(); System.exit(0); @@ -223,23 +226,28 @@ void printHelp() { - System.out.println("Usage: kinit " + - "[-A] [-f] [-p] [-c cachename] " + - "[[-k [-t keytab_file_name]] [principal] " + + System.out.println("Usage:\n\n1. Initial ticket request:\n" + + " kinit [-A] [-f] [-p] [-c cachename] " + + "[-l lifetime] [-r renewable_time]\n" + + " [[-k [-t keytab_file_name]] [principal] " + "[password]"); - System.out.println("\tavailable options to " + + System.out.println("2. Renew a ticket:\n" + + " kinit -R [-c cachename] [principal]"); + System.out.println("\nAvailable options to " + "Kerberos 5 ticket request:"); - System.out.println("\t -A do not include addresses"); - System.out.println("\t -f forwardable"); - System.out.println("\t -p proxiable"); - System.out.println("\t -c cache name " + - "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)"); - System.out.println("\t -k use keytab"); - System.out.println("\t -t keytab file name"); - System.out.println("\t principal the principal name "+ - "(i.e., qweadf@ATHENA.MIT.EDU qweadf)"); - System.out.println("\t password " + - "the principal's Kerberos password"); + System.out.println("\t-A do not include addresses"); + System.out.println("\t-f forwardable"); + System.out.println("\t-p proxiable"); + System.out.println("\t-c cache name " + + "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)"); + System.out.println("\t-l lifetime"); + System.out.println("\t-r renewable time " + + "(total lifetime a ticket can be renewed)"); + System.out.println("\t-k use keytab"); + System.out.println("\t-t keytab file name"); + System.out.println("\tprincipal the principal name "+ + "(i.e., qweadf@ATHENA.MIT.EDU qweadf)"); + System.out.println("\tpassword the principal's Kerberos password"); } public boolean getAddressOption() { @@ -257,4 +265,8 @@ public PrincipalName getPrincipal() { return principal; } + + private KerberosTime getTime(int s) { + return new KerberosTime(Instant.now().plusSeconds(s)); + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/java/lang/ProcessImpl_md.c openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/java/lang/ProcessImpl_md.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/java/lang/ProcessImpl_md.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/java/lang/ProcessImpl_md.c 2020-01-15 20:05:09.000000000 +0000 @@ -421,10 +421,10 @@ Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env, jclass ignored, jlong handle, - jlong timeout) + jlong timeoutMillis) { HANDLE events[2]; - DWORD dwTimeout = (DWORD)timeout; + DWORD dwTimeout = (DWORD)timeoutMillis; DWORD result; events[0] = (HANDLE) handle; events[1] = JVM_GetThreadInterruptEvent(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -53,17 +53,17 @@ * AccessBridgeATInstance descructor */ AccessBridgeATInstance::~AccessBridgeATInstance() { - PrintDebugString("\r\nin AccessBridgeATInstance::~AccessBridgeATInstance"); + PrintDebugString("[INFO]: in AccessBridgeATInstance::~AccessBridgeATInstance"); // if IPC memory mapped file view is valid, unmap it if (memoryMappedView != (char *) 0) { - PrintDebugString(" unmapping memoryMappedView; view = %p", memoryMappedView); + PrintDebugString("[INFO]: unmapping memoryMappedView; view = %p", memoryMappedView); UnmapViewOfFile(memoryMappedView); memoryMappedView = (char *) 0; } // if IPC memory mapped file handle map is open, close it if (memoryMappedFileMapHandle != (HANDLE) 0) { - PrintDebugString(" closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle); + PrintDebugString("[INFO]: closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle); CloseHandle(memoryMappedFileMapHandle); memoryMappedFileMapHandle = (HANDLE) 0; } @@ -87,7 +87,7 @@ AccessBridgeATInstance::initiateIPC() { DWORD errorCode; - PrintDebugString("\r\nin AccessBridgeATInstance::initiateIPC()"); + PrintDebugString("[INFO]: In AccessBridgeATInstance::initiateIPC()"); // open Windows-initiated IPC filemap & map it to a ptr @@ -95,10 +95,10 @@ FALSE, memoryMappedFileName); if (memoryMappedFileMapHandle == NULL) { errorCode = GetLastError(); - PrintDebugString(" Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode); + PrintDebugString("[ERROR]: Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode); return errorCode; } else { - PrintDebugString(" CreateFileMapping worked - filename: %s", memoryMappedFileName); + PrintDebugString("[INFO]: CreateFileMapping worked - filename: %s", memoryMappedFileName); } memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle, @@ -106,20 +106,20 @@ 0, 0, 0); if (memoryMappedView == NULL) { errorCode = GetLastError(); - PrintDebugString(" Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode); + PrintDebugString("[ERROR]: Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode); return errorCode; } else { - PrintDebugString(" MapViewOfFile worked - view: %p", memoryMappedView); + PrintDebugString("[INFO]: MapViewOfFile worked - view: %p", memoryMappedView); } // look for the JavaDLL's answer to see if it could read the file if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY) != 0) { - PrintDebugString(" JavaVM failed to write to memory mapped file %s", + PrintDebugString("[ERROR]: JavaVM failed to write to memory mapped file %s", memoryMappedFileName); return -1; } else { - PrintDebugString(" JavaVM successfully wrote to file!"); + PrintDebugString("[INFO]: JavaVM successfully wrote to file!"); } @@ -213,8 +213,8 @@ LRESULT AccessBridgeATInstance::sendJavaEventPackage(char *buffer, int bufsize, long eventID) { - PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID); - PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID); + PrintDebugString("[INFO]: AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID); + PrintDebugString("[INFO]: AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID); if (eventID & javaEventMask) { do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); @@ -234,7 +234,7 @@ LRESULT AccessBridgeATInstance::sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID) { - PrintDebugString("AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID); + PrintDebugString("[INFO]: AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID); if (eventID & accessibilityEventMask) { do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,17 +31,66 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif +static FILE* logFP = nullptr; + +void initializeFileLogger(char * fileName) { + auto var = "JAVA_ACCESSBRIDGE_LOGDIR"; + const auto envfilePath = getenv(var); + if (envfilePath != nullptr && fileName != nullptr) { + auto envFilePathLength = strlen(envfilePath); + auto fileNameLength = strlen(fileName); + auto filePathSize = envFilePathLength + 1 + fileNameLength + 5; //1 for "/", 5 for ".log" and 0; + auto filePath = new char[filePathSize]; + memset(filePath, 0, filePathSize*sizeof(char)); + memcpy(filePath, envfilePath, envFilePathLength*sizeof(char)); + filePath[envFilePathLength] = '/'; + memcpy(filePath + envFilePathLength + 1, fileName, fileNameLength*sizeof(char)); + memcpy(filePath + envFilePathLength + 1 + fileNameLength, ".log", 4*sizeof(char)); + + logFP = fopen(filePath, "w"); + if (logFP == nullptr) { + printf("\n%s\n", filePath); + PrintDebugString("Could not open file %s", filePath); + } + + delete [] filePath; + } +} + +void finalizeFileLogger() { + if (logFP) { + fclose(logFP); + logFP = nullptr; + } +} + +auto getTimeStamp() -> long long { + LARGE_INTEGER freqLarge; + ::QueryPerformanceFrequency(&freqLarge); + long long freq = freqLarge.QuadPart; + LARGE_INTEGER counterLarge; + ::QueryPerformanceCounter(&counterLarge); + long long counter = counterLarge.QuadPart; + long long milliDen = 1000; + // prevent possible overflow + long long whole = (counter / freq) * milliDen; + long long part = (counter % freq) * milliDen / freq; + return whole + part; +} + /** * Send debugging info to the appropriate place */ void PrintDebugString(char *msg, ...) { #ifdef DEBUGGING_ON - char buf[1024]; + char buf[1024] = {0}; va_list argprt; va_start(argprt, msg); // set up argptr @@ -54,6 +103,14 @@ printf("\r\n"); #endif #endif + if (logFP) { + fprintf(logFP, "[%llu] ", getTimeStamp()); + va_list args; + va_start(args, msg); + vfprintf(logFP, msg, args); + va_end(args); + fprintf(logFP, "\r\n"); + } } /** @@ -61,7 +118,7 @@ */ void PrintJavaDebugString2(char *msg, ...) { #ifdef JAVA_DEBUGGING_ON - char buf[1024]; + char buf[1024] = {0}; va_list argprt; va_start(argprt, msg); // set up argptr @@ -74,13 +131,21 @@ printf("\r\n"); #endif #endif + if (logFP) { + fprintf(logFP, "[%llu] ", getTimeStamp()); + va_list args; + va_start(args, msg); + vfprintf(logFP, msg, args); + va_end(args); + fprintf(logFP, "\r\n"); + } } /** * Wide version of the method to send debugging info to the appropriate place */ void wPrintDebugString(wchar_t *msg, ...) { #ifdef DEBUGGING_ON - char buf[1024]; + char buf[1024] = {0}; char charmsg[256]; va_list argprt; @@ -95,6 +160,14 @@ printf("\r\n"); #endif #endif + if (logFP) { + fprintf(logFP, "[%llu] ", getTimeStamp()); + va_list args; + va_start(args, msg); + vfwprintf(logFP, msg, args); + va_end(args); + fprintf(logFP, "\r\n"); + } } /** @@ -102,8 +175,8 @@ */ void wPrintJavaDebugString(wchar_t *msg, ...) { #ifdef JAVA_DEBUGGING_ON - char buf[1024]; - char charmsg[256]; + char buf[1024] = {0}; + char charmsg[256] = {0}; va_list argprt; va_start(argprt, msg); // set up argptr @@ -117,6 +190,14 @@ printf("\r\n"); #endif #endif + if (logFP) { + fprintf(logFP, "[%llu] ", getTimeStamp()); + va_list args; + va_start(args, msg); + vfwprintf(logFP, msg, args); + va_end(args); + fprintf(logFP, "\r\n"); + } } #ifdef __cplusplus } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.h openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.h --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.h 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeDebug.h 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,8 @@ void PrintJavaDebugString(char *msg, ...); void wPrintJavaDebugString(wchar_t *msg, ...); void wPrintDebugString(wchar_t *msg, ...); + void initializeFileLogger(char * fileName); + void finalizeFileLogger(); #ifdef __cplusplus } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -170,7 +170,7 @@ if (propertyChangeFP != (AccessBridge_PropertyChangeFP) 0) { propertyChangeFP(vmID, event, source, property, oldName, newName); } else { - DEBUG_CODE(AppendToCallInfo(" Error! propertyChangeFP == 0\r\n")); + DEBUG_CODE(AppendToCallInfo("[ERROR]: propertyChangeFP == 0")); } } @@ -186,9 +186,9 @@ * */ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) -const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n"; +const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n"; #else // JOBJECT64 is jlong (64 bit) -const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n"; +const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n"; #endif #define FIRE_EVENT(method, FPprototype, eventFP) \ @@ -199,18 +199,18 @@ if (eventFP != (FPprototype) 0) { \ eventFP(vmID, event, source); \ } else { \ - DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0")); \ } \ } void AccessBridgeEventHandler::fireJavaShutdown(long vmID) { DEBUG_CODE(char debugBuf[255]); - DEBUG_CODE(sprintf(debugBuf, "\r\nCalling fireJavaShutdown; vmID = %X\r\n", vmID)); + DEBUG_CODE(sprintf(debugBuf, "[INFO]: Calling fireJavaShutdown; vmID = %X\r\n", vmID)); DEBUG_CODE(AppendToCallInfo(debugBuf)); if (javaShutdownFP != (AccessBridge_JavaShutdownFP) 0) { javaShutdownFP(vmID); } else { - DEBUG_CODE(AppendToCallInfo(" Error! javaShutdownFP == 0\r\n")); + DEBUG_CODE(AppendToCallInfo("[ERROR]: javaShutdownFP == 0")); } } @@ -241,9 +241,9 @@ * */ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) -const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n"; +const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n"; #else // JOBJECT64 is jlong (64 bit) -const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n"; +const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n"; #endif #define FIRE_PROPERTY_CHANGE(method, FPprototype, eventFP) \ @@ -254,7 +254,7 @@ if (eventFP != (FPprototype) 0) { \ eventFP(vmID, event, source); \ } else { \ - DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0")); \ } \ } @@ -269,9 +269,9 @@ * */ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) -const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n"; +const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n"; #else // JOBJECT64 is jlong (64 bit) -const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n"; +const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n"; #endif #define FIRE_STRING_PROPERTY_CHANGE(method, FPprototype, eventFP, oldValue, newValue) \ @@ -283,7 +283,7 @@ if (eventFP != (FPprototype) 0) { \ eventFP(vmID, event, source, oldValue, newValue); \ } else { \ - DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \ } \ } @@ -298,9 +298,9 @@ * */ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) -const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n"; +const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n"; #else // JOBJECT64 is jlong (64 bit) -const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n"; +const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n"; #endif #define FIRE_INT_PROPERTY_CHANGE(method, FPprototype, eventFP) \ @@ -312,7 +312,7 @@ if (eventFP != (FPprototype) 0) { \ eventFP(vmID, event, source, oldValue, newValue); \ } else { \ - DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \ } \ } @@ -327,9 +327,9 @@ * */ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) -const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n"; +const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n"; #else // JOBJECT64 is jlong (64 bit) -const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n"; +const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n"; #endif #define FIRE_AC_PROPERTY_CHANGE(method, FPprototype, eventFP) \ @@ -341,7 +341,7 @@ if (eventFP != (FPprototype) 0) { \ eventFP(vmID, event, source, oldValue, newValue); \ } else { \ - DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \ } \ } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -40,7 +40,7 @@ jobject bridgeObject) { jniEnv = jniEnvironment; accessBridgeObject = (jobject)bridgeObject; - PrintDebugString("AccessBridgeJavaEntryPoints(%X, %X) called", jniEnv, accessBridgeObject); + PrintDebugString("[INFO]: AccessBridgeJavaEntryPoints(%p, %p) called", jniEnv, accessBridgeObject); } @@ -56,15 +56,13 @@ #define FIND_CLASS(classRef, className) \ localClassRef = jniEnv->FindClass(className); \ if (localClassRef == (jclass) 0) { \ - PrintDebugString(" Error! FindClass(%s) failed!", className); \ - PrintDebugString(" -> jniEnv = %p", jniEnv); \ + PrintDebugString("[ERROR]: FindClass(%s) failed! -> jniEnv = %p", className, jniEnv); \ return FALSE; \ } \ classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \ jniEnv->DeleteLocalRef(localClassRef); \ if (classRef == (jclass) 0) { \ - PrintDebugString(" Error! FindClass(%s) failed!", className); \ - PrintDebugString(" -> (ran out of RAM)"); \ + PrintDebugString("[ERROR]: FindClass(%s) failed! -> (ran out of RAM)", className); \ return FALSE; \ } @@ -72,14 +70,13 @@ #define FIND_METHOD(methodID, classRef, methodString, methodSignature); \ methodID = jniEnv->GetMethodID(classRef, methodString, methodSignature); \ if (methodID == (jmethodID) 0) { \ - PrintDebugString(" Error! GetMethodID(%s) failed!", methodString); \ - PrintDebugString(" -> jniEnv = %p; classRef = %p", jniEnv, classRef); \ + PrintDebugString("[ERROR]: GetMethodID(%s) failed! -> jniEnv = %p; classRef = %p", methodString, jniEnv, classRef); \ return FALSE; \ } #define EXCEPTION_CHECK(situationDescription, returnVal) \ if (exception = jniEnv->ExceptionOccurred()) { \ - PrintDebugString("\r\n *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ jniEnv->ExceptionDescribe(); \ jniEnv->ExceptionClear(); \ return (returnVal); \ @@ -87,7 +84,7 @@ #define EXCEPTION_CHECK_VOID(situationDescription) \ if (exception = jniEnv->ExceptionOccurred()) { \ - PrintDebugString("\r\n *** Exception occured while doing: %s", situationDescription); \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription); \ jniEnv->ExceptionDescribe(); \ jniEnv->ExceptionClear(); \ return; \ @@ -101,7 +98,7 @@ AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() { jclass localClassRef; - PrintDebugString("Calling BuildJavaEntryPoints():"); + PrintDebugString("[INFO]: Calling BuildJavaEntryPoints():"); FIND_CLASS(bridgeClass, "com/sun/java/accessibility/AccessBridge"); @@ -886,14 +883,14 @@ jthrowable exception; BOOL returnVal; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window); if (isJavaWindowMethod != (jmethodID) 0) { returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window); EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE); return returnVal; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or isJavaWindowMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or isJavaWindowMethod == 0"); return FALSE; } } @@ -909,12 +906,12 @@ jthrowable exception; BOOL returnVal; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2); + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2); returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2); EXCEPTION_CHECK("Calling IsSameObject", FALSE); - PrintDebugString("\r\n isSameObject returning %d", returnVal); + PrintDebugString("[INFO]: isSameObject returning %d", returnVal); return returnVal; } @@ -930,7 +927,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window); + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window); if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) { returnedAccessibleContext = @@ -941,7 +938,7 @@ EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0); return globalRef; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0"); return (jobject) 0; } } @@ -957,17 +954,17 @@ jthrowable exception; HWND rHWND; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):", accessibleContext); if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) { rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod, accessibleContext); EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0); - PrintDebugString("\r\n rHWND = %X", rHWND); + PrintDebugString("[INFO]: rHWND = %X", rHWND); return rHWND; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0"); return (HWND)0; } } @@ -983,7 +980,7 @@ jthrowable exception; BOOL result = FALSE; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):", accessibleContext, text); if (setTextContentsMethod != (jmethodID) 0) { @@ -991,7 +988,7 @@ // create a Java String for the text jstring textString = jniEnv->NewString(text, (jsize)wcslen(text)); if (textString == 0) { - PrintDebugString("\r NewString failed"); + PrintDebugString("[ERROR]: NewString failed"); return FALSE; } @@ -999,10 +996,10 @@ setTextContentsMethod, accessibleContext, textString); EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE); - PrintDebugString("\r\n result = %d", result); + PrintDebugString("[INFO]: result = %d", result); return result; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or setTextContentsMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or setTextContentsMethod == 0"); return result; } } @@ -1020,14 +1017,14 @@ jthrowable exception; jobject rAccessibleContext; - PrintDebugString("In AccessBridgeJavaEntryPoints::getParentWithRole(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRole(%p):", accessibleContext); if (getParentWithRoleMethod != (jmethodID) 0) { // create a Java String for the role jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); if (roleName == 0) { - PrintDebugString(" NewString failed"); + PrintDebugString("[ERROR]: NewString failed"); return FALSE; } @@ -1035,14 +1032,14 @@ getParentWithRoleMethod, accessibleContext, roleName); EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0); - PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + PrintDebugString("[INFO]: rAccessibleContext = %p", rAccessibleContext); jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", rAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getParentWithRoleMethod == 0"); return 0; } } @@ -1058,7 +1055,7 @@ jthrowable exception; jobject rAccessibleContext; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTopLevelObject(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTopLevelObject(%p):", accessibleContext); if (getTopLevelObjectMethod != (jmethodID) 0) { @@ -1066,14 +1063,14 @@ getTopLevelObjectMethod, accessibleContext); EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE); - PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + PrintDebugString("[INFO]: rAccessibleContext = %p", rAccessibleContext); jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", rAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getTopLevelObjectMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getTopLevelObjectMethod == 0"); return 0; } } @@ -1089,7 +1086,7 @@ jthrowable exception; jobject rAccessibleContext; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):", accessibleContext); if (getParentWithRoleElseRootMethod != (jmethodID) 0) { @@ -1097,7 +1094,7 @@ // create a Java String for the role jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); if (roleName == 0) { - PrintDebugString("\r NewString failed"); + PrintDebugString("[ERROR]: NewString failed"); return FALSE; } @@ -1105,14 +1102,14 @@ getParentWithRoleElseRootMethod, accessibleContext, roleName); EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0); - PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + PrintDebugString("[INFO]: rAccessibleContext = %p", rAccessibleContext); jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", rAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleElseRootMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getParentWithRoleElseRootMethod == 0"); return 0; } } @@ -1127,7 +1124,7 @@ jthrowable exception; jint rResult; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getObjectDepth(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getObjectDepth(%p):", accessibleContext); if (getObjectDepthMethod != (jmethodID) 0) { @@ -1135,10 +1132,10 @@ getObjectDepthMethod, accessibleContext); EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1); - PrintDebugString("\r\n rResult = %d", rResult); + PrintDebugString("[INFO]: rResult = %d", rResult); return rResult; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getObjectDepthMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getObjectDepthMethod == 0"); return -1; } } @@ -1154,7 +1151,7 @@ jthrowable exception; jobject rAccessibleContext; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getActiveDescendent(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getActiveDescendent(%p):", accessibleContext); if (getActiveDescendentMethod != (jmethodID) 0) { @@ -1162,14 +1159,14 @@ getActiveDescendentMethod, accessibleContext); EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0); - PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + PrintDebugString("[INFO]: rAccessibleContext = %p", rAccessibleContext); jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", rAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getActiveDescendentMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getActiveDescendentMethod == 0"); return (AccessibleContext)0; } } @@ -1210,7 +1207,7 @@ const wchar_t * stringBytes = NULL; jthrowable exception = NULL; jsize length = 0; - PrintDebugString("\r\n getVirtualAccessibleName called."); + PrintDebugString("[INFO]: getVirtualAccessibleName called."); if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0) { js = (jstring) jniEnv->CallObjectMethod ( @@ -1231,18 +1228,18 @@ accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Name = %ls", name); + wPrintDebugString(L"[INFO]: Accessible Name = %ls", name); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Name is null."); + PrintDebugString("[INFO]: Accessible Name is null."); } } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0"); + PrintDebugString("[INFO]: either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0"); return FALSE; } if ( 0 != name [0] ) @@ -1264,7 +1261,7 @@ jthrowable exception; BOOL result = FALSE; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::requestFocus(%p):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::requestFocus(%p):", accessibleContext); if (requestFocusMethod != (jmethodID) 0) { @@ -1272,10 +1269,10 @@ requestFocusMethod, accessibleContext); EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE); - PrintDebugString("\r\n result = %d", result); + PrintDebugString("[INFO]: result = %d", result); return result; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or requestFocusMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or requestFocusMethod == 0"); return result; } } @@ -1292,7 +1289,7 @@ jthrowable exception; BOOL result = FALSE; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):", accessibleContext, startIndex, endIndex); if (selectTextRangeMethod != (jmethodID) 0) { @@ -1301,10 +1298,10 @@ accessibleContext, startIndex, endIndex); EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE); - PrintDebugString("\r\n result = %d", result); + PrintDebugString("[INFO]: result = %d", result); return result; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or selectTextRangeMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or selectTextRangeMethod == 0"); return result; } } @@ -1361,7 +1358,7 @@ jsize length; BOOL result = FALSE; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):", accessibleContext, startIndex, endIndex); *len = 0; @@ -1376,12 +1373,12 @@ AccessibleTextAttributesInfo test_attributes = *attributes; // Get the full test_attributes string at i if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { - PrintDebugString(" Getting full test_attributes string from Context..."); + PrintDebugString("[INFO]: Getting full test_attributes string from Context..."); js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleAttributesAtIndexFromContextMethod, accessibleContext, i); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); @@ -1395,16 +1392,16 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Text attributes = %ls", test_attributes.fullAttributesString); + wPrintDebugString(L"[INFO]: Accessible Text attributes = %ls", test_attributes.fullAttributesString); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Text attributes is null."); + PrintDebugString("[WARN]: Accessible Text attributes is null."); test_attributes.fullAttributesString[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); return FALSE; } @@ -1427,14 +1424,14 @@ AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) { jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)", accessibleContext); // get the visible children count int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### visible children count = %d", numChildren); + PrintDebugString("[INFO]: ##### visible children count = %d", numChildren); return numChildren; } @@ -1454,14 +1451,14 @@ jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)", accessibleContext, nStartIndex); // get the visible children count int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### visible children count = %d", numChildren); + PrintDebugString("[INFO]: ##### visible children count = %d", numChildren); if (nStartIndex >= numChildren) { return FALSE; @@ -1470,7 +1467,7 @@ // get the visible children int bufIndex = 0; for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) { - PrintDebugString(" getting visible child %d ...", i); + PrintDebugString("[INFO]: getting visible child %d ...", i); // get the visible child at index i jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod, @@ -1479,13 +1476,13 @@ jobject globalRef = jniEnv->NewGlobalRef(ac); EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE); visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef; - PrintDebugString(" ##### visible child = %p", globalRef); + PrintDebugString("[INFO]: ##### visible child = %p", globalRef); bufIndex++; } visibleChildrenInfo->returnedChildrenCount = bufIndex; - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded"); return TRUE; } @@ -1500,7 +1497,7 @@ jthrowable exception; BOOL result = FALSE; - PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):", + PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):", accessibleContext, position); if (setCaretPositionMethod != (jmethodID) 0) { @@ -1508,10 +1505,10 @@ setCaretPositionMethod, accessibleContext, position); EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE); - PrintDebugString("\r\n result = %d", result); + PrintDebugString("[ERROR]: result = %d", result); return result; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or setCaretPositionMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or setCaretPositionMethod == 0"); return result; } } @@ -1531,19 +1528,19 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getVersionInfo():"); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getVersionInfo():"); if (getJavaVersionPropertyMethod != (jmethodID) 0) { js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getJavaVersionPropertyMethod); EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { length = jniEnv->GetStringLength(js); stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); if (stringBytes == NULL) { if (!jniEnv->ExceptionCheck()) { - PrintDebugString("\r\n *** Exception when getting JavaVersionProperty - call to GetStringChars"); + PrintDebugString("[ERROR]: *** Exception when getting JavaVersionProperty - call to GetStringChars"); jniEnv->ExceptionDescribe(); jniEnv->ExceptionClear(); } @@ -1574,16 +1571,16 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Java version = %ls", info->VMversion); + wPrintDebugString(L"[INFO]: Java version = %ls", info->VMversion); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Java version is null."); + PrintDebugString("[WARN]: Java version is null."); info->VMversion[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getJavaVersionPropertyMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getJavaVersionPropertyMethod == 0"); return FALSE; } @@ -1600,15 +1597,15 @@ BOOL retval; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::verifyAccessibleText"); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::verifyAccessibleText"); if (jniEnv->GetJavaVM(&vm) != 0) { - PrintDebugString(" Error! No Java VM"); + PrintDebugString("[ERROR]: No Java VM"); return FALSE; } if (obj == (jobject)0) { - PrintDebugString(" Error! Null jobject"); + PrintDebugString("[ERROR]: Null jobject"); return FALSE; } @@ -1618,16 +1615,16 @@ getAccessibleTextFromContextMethod, (jobject)obj); EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleText = %p", returnedJobject); + PrintDebugString("[ERROR]: AccessibleText = %p", returnedJobject); retval = returnedJobject != (jobject) 0; jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextFromContextMethod == 0"); return FALSE; } if (retval == FALSE) { - PrintDebugString(" Error! jobject is not an AccessibleText"); + PrintDebugString("[ERROR]: jobject is not an AccessibleText"); } return retval; } @@ -1652,7 +1649,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):", x, y, accessibleContext); if (getAccessibleContextAtMethod != (jmethodID) 0) { @@ -1662,11 +1659,11 @@ EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE); globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleContextAtMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleContextAtMethod == 0"); return (jobject) 0; } } @@ -1687,7 +1684,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()"); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()"); if (getAccessibleContextWithFocusMethod != (jmethodID) 0) { returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, @@ -1695,11 +1692,11 @@ EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE); globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0"); return (jobject) 0; } } @@ -1724,12 +1721,12 @@ jthrowable exception; jsize length; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext); + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext); ZeroMemory(info, sizeof(AccessibleContextInfo)); if (accessibleContext == (jobject) 0) { - PrintDebugString(" passed in AccessibleContext == null! (oops)"); + PrintDebugString("[WARN]: passed in AccessibleContext == null! (oops)"); return (FALSE); } @@ -1752,15 +1749,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Name = %ls", info->name); + wPrintDebugString(L"[INFO]: Accessible Name = %ls", info->name); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Name is null."); + PrintDebugString("[WARN]: Accessible Name is null."); info->name[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleNameFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleNameFromContextMethod == 0"); return FALSE; } @@ -1784,15 +1781,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Description = %ls", info->description); + wPrintDebugString(L"[INFO]: Accessible Description = %ls", info->description); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Description is null."); + PrintDebugString("[WARN]: Accessible Description is null."); info->description[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleDescriptionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleDescriptionFromContextMethod == 0"); return FALSE; } @@ -1816,15 +1813,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Role = %ls", info->role); + wPrintDebugString(L"[INFO]: Accessible Role = %ls", info->role); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Role is null."); + PrintDebugString("[WARN]: Accessible Role is null."); info->role[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleRoleStringFromContextMethod == 0"); return FALSE; } @@ -1848,15 +1845,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Role en_US = %ls", info->role_en_US); + wPrintDebugString(L"[INFO]: Accessible Role en_US = %ls", info->role_en_US); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Role en_US is null."); + PrintDebugString("[WARN]: Accessible Role en_US is null."); info->role[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0"); return FALSE; } @@ -1879,15 +1876,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible States = %ls", info->states); + wPrintDebugString(L"[INFO]: Accessible States = %ls", info->states); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible States is null."); + PrintDebugString("[WARN]: Accessible States is null."); info->states[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleStatesStringFromContextMethod == 0"); return FALSE; } @@ -1910,15 +1907,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible States en_US = %ls", info->states_en_US); + wPrintDebugString(L"[INFO]: Accessible States en_US = %ls", info->states_en_US); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible States en_US is null."); + PrintDebugString("[WARN]: Accessible States en_US is null."); info->states[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0"); return FALSE; } @@ -1929,14 +1926,14 @@ getAccessibleIndexInParentFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE); - PrintDebugString(" Index in Parent = %d", info->indexInParent); + PrintDebugString("[INFO]: Index in Parent = %d", info->indexInParent); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleIndexInParentFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleIndexInParentFromContextMethod == 0"); return FALSE; } - PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***", + PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***", jniEnv, accessBridgeObject, accessibleContext); // Get the children count @@ -1945,13 +1942,13 @@ getAccessibleChildrenCountFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE); - PrintDebugString(" Children count = %d", info->childrenCount); + PrintDebugString("[INFO]: Children count = %d", info->childrenCount); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleChildrenCountFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleChildrenCountFromContextMethod == 0"); return FALSE; } - PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***", + PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***", jniEnv, accessBridgeObject, accessibleContext); @@ -1961,13 +1958,13 @@ getAccessibleXcoordFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE); - PrintDebugString(" X coord = %d", info->x); + PrintDebugString("[INFO]: X coord = %d", info->x); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleXcoordFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleXcoordFromContextMethod == 0"); return FALSE; } - PrintDebugString("*** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***", + PrintDebugString("[INFO]: *** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***", jniEnv, accessBridgeObject, accessibleContext); @@ -1977,9 +1974,9 @@ getAccessibleYcoordFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE); - PrintDebugString(" Y coord = %d", info->y); + PrintDebugString("[INFO]: Y coord = %d", info->y); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleYcoordFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleYcoordFromContextMethod == 0"); return FALSE; } @@ -1989,9 +1986,9 @@ getAccessibleWidthFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE); - PrintDebugString(" Width = %d", info->width); + PrintDebugString("[INFO]: Width = %d", info->width); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleWidthFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleWidthFromContextMethod == 0"); return FALSE; } @@ -2001,9 +1998,9 @@ getAccessibleHeightFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE); - PrintDebugString(" Height = %d", info->height); + PrintDebugString("[INFO]: Height = %d", info->height); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleHeightFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleHeightFromContextMethod == 0"); return FALSE; } @@ -2013,12 +2010,12 @@ getAccessibleComponentFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleComponent = %p", returnedJobject); + PrintDebugString("[INFO]: AccessibleComponent = %p", returnedJobject); info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE); jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleComponentFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleComponentFromContextMethod == 0"); return FALSE; } @@ -2028,12 +2025,12 @@ getAccessibleActionFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleAction = %p", returnedJobject); + PrintDebugString("[INFO]: AccessibleAction = %p", returnedJobject); info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE); jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleActionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleActionFromContextMethod == 0"); return FALSE; } @@ -2043,24 +2040,24 @@ getAccessibleSelectionFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleSelection = %p", returnedJobject); + PrintDebugString("[INFO]: AccessibleSelection = %p", returnedJobject); info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE); jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleSelectionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionFromContextMethod == 0"); return FALSE; } // Get the AccessibleTable if (getAccessibleTableFromContextMethod != (jmethodID) 0) { - PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ..."); returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleTableFromContextMethod, accessibleContext); - PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod"); EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); - PrintDebugString(" ##### AccessibleTable = %p", returnedJobject); + PrintDebugString("[INFO]: ##### AccessibleTable = %p", returnedJobject); if (returnedJobject != (jobject) 0) { info->accessibleInterfaces |= cAccessibleTableInterface; } @@ -2078,7 +2075,7 @@ */ } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0"); return FALSE; } @@ -2088,12 +2085,12 @@ getAccessibleTextFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleText = %p", returnedJobject); + PrintDebugString("[INFO]: AccessibleText = %p", returnedJobject); info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE); jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextFromContextMethod == 0"); return FALSE; } @@ -2103,14 +2100,14 @@ getAccessibleValueFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleValue = %p", returnedJobject); + PrintDebugString("[INFO]: AccessibleValue = %p", returnedJobject); if (returnedJobject != (jobject) 0) { info->accessibleInterfaces |= cAccessibleValueInterface; } jniEnv->DeleteLocalRef(returnedJobject); EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleValueFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleValueFromContextMethod == 0"); return FALSE; } @@ -2126,7 +2123,7 @@ getAccessibleHypertextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); - PrintDebugString(" AccessibleHypertext = %p", + PrintDebugString("[INFO]: AccessibleHypertext = %p", returnedJobject); if (returnedJobject != (jobject) 0) { info->accessibleInterfaces |= cAccessibleHypertextInterface; @@ -2167,7 +2164,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):", accessibleContext, childIndex); if (getAccessibleChildFromContextMethod != (jmethodID) 0) { @@ -2179,11 +2176,11 @@ EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE); jniEnv->DeleteLocalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleChildContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleChildContextMethod == 0"); return (jobject) 0; } } @@ -2199,7 +2196,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext); if (getAccessibleParentFromContextMethod != (jmethodID) 0) { returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, @@ -2210,11 +2207,11 @@ EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE); jniEnv->DeleteLocalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleParentFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleParentFromContextMethod == 0"); return (jobject) 0; } } @@ -2228,7 +2225,7 @@ jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):", accessibleContext); // get the table row count @@ -2237,9 +2234,9 @@ getAccessibleTableRowCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + PrintDebugString("[INFO]: ##### table row count = %d", tableInfo->rowCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0"); return FALSE; } @@ -2249,43 +2246,43 @@ getAccessibleTableColumnCountMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + PrintDebugString("[INFO]: ##### table column count = %d", tableInfo->columnCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnCountMethod == 0"); return FALSE; } // get the AccessibleTable if (getAccessibleTableFromContextMethod != (jmethodID) 0) { - PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ..."); jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleTableFromContextMethod, accessibleContext); - PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod"); EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); jobject globalRef = jniEnv->NewGlobalRef(accTable); EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); tableInfo->accessibleTable = (JOBJECT64)globalRef; - PrintDebugString(" ##### accessibleTable = %p", globalRef); + PrintDebugString("[INFO]: ##### accessibleTable = %p", globalRef); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0"); return FALSE; } // cache the AccessibleContext if (getContextFromAccessibleTableMethod != (jmethodID) 0) { - PrintDebugString("##### Calling getContextFromAccessibleTable Method ..."); + PrintDebugString("[INFO]: ##### Calling getContextFromAccessibleTable Method ..."); jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getContextFromAccessibleTableMethod, accessibleContext); - PrintDebugString("##### ... Returned from getContextFromAccessibleTable Method"); + PrintDebugString("[INFO]: ##### ... Returned from getContextFromAccessibleTable Method"); EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); jobject globalRef = jniEnv->NewGlobalRef(ac); EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); tableInfo->accessibleContext = (JOBJECT64)globalRef; - PrintDebugString(" ##### accessibleContext = %p", globalRef); + PrintDebugString("[INFO]: ##### accessibleContext = %p", globalRef); } else { - PrintDebugString(" ##### Error! either env == 0 or getContextFromAccessibleTable Method == 0"); + PrintDebugString("[ERROR]: either env == 0 or getContextFromAccessibleTable Method == 0"); return FALSE; } @@ -2293,7 +2290,7 @@ tableInfo->caption = NULL; tableInfo->summary = NULL; - PrintDebugString("##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded"); + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded"); return TRUE; } @@ -2303,7 +2300,7 @@ jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d", accessibleTable, row, column); // FIX @@ -2318,9 +2315,9 @@ getAccessibleTableCellIndexMethod, accessibleTable, row, column); EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table cell index = %d", tableCellInfo->index); + PrintDebugString("[INFO]: ##### table cell index = %d", tableCellInfo->index); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellIndexMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellIndexMethod == 0"); return FALSE; } @@ -2330,9 +2327,9 @@ getAccessibleTableCellRowExtentMethod, accessibleTable, row, column); EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table cell row extent = %d", tableCellInfo->rowExtent); + PrintDebugString("[INFO]: ##### table cell row extent = %d", tableCellInfo->rowExtent); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellRowExtentMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellRowExtentMethod == 0"); return FALSE; } @@ -2342,9 +2339,9 @@ getAccessibleTableCellColumnExtentMethod, accessibleTable, row, column); EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table cell column extent = %d", tableCellInfo->columnExtent); + PrintDebugString("[INFO]: ##### table cell column extent = %d", tableCellInfo->columnExtent); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellColumnExtentMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellColumnExtentMethod == 0"); return FALSE; } @@ -2354,9 +2351,9 @@ isAccessibleTableCellSelectedMethod, accessibleTable, row, column); EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE); - PrintDebugString(" ##### table cell isSelected = %d", tableCellInfo->isSelected); + PrintDebugString("[INFO]: ##### table cell isSelected = %d", tableCellInfo->isSelected); } else { - PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableCellSelectedMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableCellSelectedMethod == 0"); return FALSE; } @@ -2369,13 +2366,13 @@ jobject globalRef = jniEnv->NewGlobalRef(tableCellAC); EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE); tableCellInfo->accessibleContext = (JOBJECT64)globalRef; - PrintDebugString(" ##### table cell AccessibleContext = %p", globalRef); + PrintDebugString("[INFO]: ##### table cell AccessibleContext = %p", globalRef); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0"); return FALSE; } - PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded"); + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded"); return TRUE; } @@ -2384,7 +2381,7 @@ jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):", acParent); // get the header row count @@ -2393,9 +2390,9 @@ getAccessibleTableRowHeaderRowCountMethod, acParent); EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + PrintDebugString("[INFO]: ##### table row count = %d", tableInfo->rowCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowHeaderRowCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowHeaderRowCountMethod == 0"); return FALSE; } @@ -2405,9 +2402,9 @@ getAccessibleTableRowHeaderColumnCountMethod, acParent); EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + PrintDebugString("[INFO]: ##### table column count = %d", tableInfo->columnCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0"); return FALSE; } @@ -2420,9 +2417,9 @@ jobject globalRef = jniEnv->NewGlobalRef(accTable); EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE); tableInfo->accessibleTable = (JOBJECT64)globalRef; - PrintDebugString(" ##### row header AccessibleTable = %p", globalRef); + PrintDebugString("[INFO]: ##### row header AccessibleTable = %p", globalRef); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderMethod == 0"); return FALSE; } @@ -2431,7 +2428,7 @@ tableInfo->summary = NULL; tableInfo->accessibleContext = NULL; - PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded"); + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded"); return TRUE; } @@ -2439,7 +2436,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) { jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):", acParent); // get the header row count @@ -2448,9 +2445,9 @@ getAccessibleTableColumnHeaderRowCountMethod, acParent); EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + PrintDebugString("[INFO]: ##### table row count = %d", tableInfo->rowCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0"); return FALSE; } @@ -2460,9 +2457,9 @@ getAccessibleTableColumnHeaderColumnCountMethod, acParent); EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + PrintDebugString("[INFO]: ##### table column count = %d", tableInfo->columnCount); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0"); return FALSE; } // get the header AccessibleTable @@ -2474,9 +2471,9 @@ jobject globalRef = jniEnv->NewGlobalRef(accTable); EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE); tableInfo->accessibleTable = (JOBJECT64)globalRef; - PrintDebugString(" ##### column header AccessibleTable = %p", globalRef); + PrintDebugString("[INFO]: ##### column header AccessibleTable = %p", globalRef); } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderMethod == 0"); return FALSE; } @@ -2485,7 +2482,7 @@ tableInfo->summary = NULL; tableInfo->accessibleContext = NULL; - PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded"); + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded"); return TRUE; } @@ -2496,7 +2493,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):", acParent); if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) { @@ -2508,11 +2505,11 @@ EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE); jniEnv->DeleteLocalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTableRowDescriptionMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowDescriptionMethod == 0"); return (jobject) 0; } } @@ -2524,7 +2521,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):", + PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):", acParent); if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) { @@ -2537,11 +2534,11 @@ EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE); jniEnv->DeleteLocalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTableColumnDescriptionMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnDescriptionMethod == 0"); return (jobject) 0; } } @@ -2552,7 +2549,7 @@ jthrowable exception; jint count; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)", accessibleTable); // Get the table row selection count @@ -2561,14 +2558,14 @@ getAccessibleTableRowSelectionCountMethod, accessibleTable); EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row selection count = %d", count); + PrintDebugString("[INFO]: ##### table row selection count = %d", count); return count; } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowSelectionCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowSelectionCountMethod == 0"); return 0; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed"); return 0; } @@ -2577,7 +2574,7 @@ jthrowable exception; BOOL result; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)", accessibleTable, row); if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) { @@ -2585,14 +2582,14 @@ isAccessibleTableRowSelectedMethod, accessibleTable, row); EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE); - PrintDebugString(" ##### table row isSelected = %d", result); + PrintDebugString("[INFO]: ##### table row isSelected = %d", result); return result; } else { - PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableRowSelectedMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableRowSelectedMethod == 0"); return FALSE; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed"); + PrintDebugString("[ERROR]: AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed"); return FALSE; } @@ -2602,7 +2599,7 @@ jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)", accessibleTable, count, selections); if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) { @@ -2616,10 +2613,10 @@ accessibleTable, i); EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row selection[%d] = %d", i, selections[i]); + PrintDebugString("[INFO]: ##### table row selection[%d] = %d", i, selections[i]); } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded"); return TRUE; } @@ -2630,7 +2627,7 @@ jthrowable exception; jint count; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)", accessibleTable); // Get the table column selection count @@ -2639,14 +2636,14 @@ getAccessibleTableColumnSelectionCountMethod, accessibleTable); EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table column selection count = %d", count); + PrintDebugString("[INFO]: ##### table column selection count = %d", count); return count; } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0"); return 0; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed"); return 0; } @@ -2655,7 +2652,7 @@ jthrowable exception; BOOL result; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)", accessibleTable, column); if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) { @@ -2663,14 +2660,14 @@ isAccessibleTableColumnSelectedMethod, accessibleTable, column); EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE); - PrintDebugString(" ##### table column isSelected = %d", result); + PrintDebugString("[INFO]: ##### table column isSelected = %d", result); return result; } else { - PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableColumnSelectedMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableColumnSelectedMethod == 0"); return FALSE; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed"); return FALSE; } @@ -2679,7 +2676,7 @@ jint *selections) { jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)", accessibleTable, count, selections); if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) { @@ -2693,10 +2690,10 @@ accessibleTable, i); EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table Column selection[%d] = %d", i, selections[i]); + PrintDebugString("[INFO]: ##### table Column selection[%d] = %d", i, selections[i]); } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded"); return TRUE; } @@ -2706,7 +2703,7 @@ jthrowable exception; jint result; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)", accessibleTable, index); if (getAccessibleTableRowMethod != (jmethodID) 0) { @@ -2714,14 +2711,14 @@ getAccessibleTableRowMethod, accessibleTable, index); EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table row = %d", result); + PrintDebugString("[INFO]: ##### table row = %d", result); return result; } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowMethod == 0"); return -1; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed"); return -1; } @@ -2730,7 +2727,7 @@ jthrowable exception; jint result; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)", accessibleTable, index); if (getAccessibleTableColumnMethod != (jmethodID) 0) { @@ -2738,14 +2735,14 @@ getAccessibleTableColumnMethod, accessibleTable, index); EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table column = %d", result); + PrintDebugString("[INFO]: ##### table column = %d", result); return result; } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnMethod == 0"); return -1; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed"); return -1; } @@ -2754,7 +2751,7 @@ jthrowable exception; jint result; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)", accessibleTable, row, column); if (getAccessibleTableIndexMethod != (jmethodID) 0) { @@ -2762,14 +2759,14 @@ getAccessibleTableIndexMethod, accessibleTable, row, column); EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### table index = %d", result); + PrintDebugString("[INFO]: ##### table index = %d", result); return result; } else { - PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableIndexMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableIndexMethod == 0"); return -1; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed"); + PrintDebugString("[ERROR]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed"); return -1; } @@ -2786,7 +2783,7 @@ const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)", accessibleContext, relationSet); if (getAccessibleRelationCountMethod == (jmethodID) 0 || @@ -2801,7 +2798,7 @@ getAccessibleRelationCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### AccessibleRelation count = %d", relationSet->relationCount); + PrintDebugString("[INFO]: ##### AccessibleRelation count = %d", relationSet->relationCount); // Get the relation set @@ -2826,11 +2823,11 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleRelation key = %ls", relationSet->relations[i].key ); + PrintDebugString("[INFO]: ##### AccessibleRelation key = %ls", relationSet->relations[i].key ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleRelation key is null."); + PrintDebugString("[WARN]: AccessibleRelation key is null."); relationSet->relations[i].key [0] = (wchar_t) 0; } @@ -2846,11 +2843,11 @@ jobject globalRef = jniEnv->NewGlobalRef(target); EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE); relationSet->relations[i].targets[j] = (JOBJECT64)globalRef; - PrintDebugString(" relation set item: %p", globalRef); + PrintDebugString("[INFO]: relation set item: %p", globalRef); } } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded"); return TRUE; } @@ -2868,7 +2865,7 @@ const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)", accessibleContext, hypertext); // get the AccessibleHypertext @@ -2879,10 +2876,10 @@ jobject globalRef = jniEnv->NewGlobalRef(ht); EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); hypertext->accessibleHypertext = (JOBJECT64)globalRef; - PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + PrintDebugString("[INFO]: ##### AccessibleHypertext = %p", globalRef); if (hypertext->accessibleHypertext == 0) { - PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + PrintDebugString("[WARN]: ##### null AccessibleHypertext; returning FALSE"); return false; } @@ -2891,7 +2888,7 @@ getAccessibleHyperlinkCountMethod,accessibleContext); EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + PrintDebugString("[INFO]: ##### hyperlink count = %d", hypertext->linkCount); // get the hypertext links @@ -2906,7 +2903,7 @@ jobject globalRef = jniEnv->NewGlobalRef(hl); EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef; - PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + PrintDebugString("[INFO]: ##### AccessibleHyperlink = %p", globalRef); // get the hyperlink text jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, @@ -2930,11 +2927,11 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[i].text ); + PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[i].text ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleHyperlink text is null."); + PrintDebugString("[WARN]: AccessibleHyperlink text is null."); hypertext->links[i].text[0] = (wchar_t) 0; } @@ -2943,7 +2940,7 @@ hypertext->links[i].accessibleHyperlink, i); EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[i].startIndex); + PrintDebugString("[INFO]: ##### hyperlink start index = %d", hypertext->links[i].startIndex); hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject, @@ -2951,11 +2948,11 @@ hypertext->links[i].accessibleHyperlink, i); EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[i].endIndex); + PrintDebugString("[INFO]: ##### hyperlink end index = %d", hypertext->links[i].endIndex); } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded"); return TRUE; } @@ -2969,7 +2966,7 @@ jthrowable exception; BOOL returnVal; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):", accessibleContext, accessibleHyperlink); if (activateAccessibleHyperlinkMethod != (jmethodID) 0) { @@ -2978,7 +2975,7 @@ EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE); return returnVal; } else { - PrintDebugString("\r\n Error! either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0"); + PrintDebugString("[ERROR]: either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0"); return FALSE; } } @@ -2999,7 +2996,7 @@ jthrowable exception; const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)", accessibleContext, hypertext, nStartIndex); // get the AccessibleHypertext @@ -3009,9 +3006,9 @@ jobject globalRef = jniEnv->NewGlobalRef(ht); EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); hypertext->accessibleHypertext = (JOBJECT64)globalRef; - PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + PrintDebugString("[INFO]: ##### AccessibleHypertext = %p", globalRef); if (hypertext->accessibleHypertext == 0) { - PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + PrintDebugString("[WARN]: ##### null AccessibleHypertext; returning FALSE"); return FALSE; } @@ -3019,7 +3016,7 @@ hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + PrintDebugString("[INFO]: ##### hyperlink count = %d", hypertext->linkCount); if (nStartIndex >= hypertext->linkCount) { return FALSE; @@ -3031,7 +3028,7 @@ // i < hypertext->linkCount int bufIndex = 0; for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) { - PrintDebugString(" getting hyperlink %d ...", i); + PrintDebugString("[INFO]: getting hyperlink %d ...", i); // get the hyperlink jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, @@ -3042,7 +3039,7 @@ jobject globalRef = jniEnv->NewGlobalRef(hl); EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef; - PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + PrintDebugString("[INFO]: ##### AccessibleHyperlink = %p", globalRef); // get the hyperlink text jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, @@ -3067,12 +3064,12 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text ); + PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleHyperlink text is null."); + PrintDebugString("[WARN]: AccessibleHyperlink text is null."); hypertext->links[bufIndex].text[0] = (wchar_t) 0; } @@ -3081,19 +3078,19 @@ hypertext->links[bufIndex].accessibleHyperlink, i); EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex); + PrintDebugString("[INFO]: ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex); hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkEndIndexMethod, hypertext->links[bufIndex].accessibleHyperlink, i); EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex); + PrintDebugString("[INFO]: ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex); bufIndex++; } - PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded"); + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded"); return TRUE; } @@ -3101,7 +3098,7 @@ jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)", accessibleContext); if (getAccessibleHyperlinkCountMethod == (jmethodID)0) { @@ -3112,7 +3109,7 @@ jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1); - PrintDebugString(" ##### hyperlink count = %d", linkCount); + PrintDebugString("[INFO]: ##### hyperlink count = %d", linkCount); return linkCount; } @@ -3123,7 +3120,7 @@ jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)", hypertext, nIndex); if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) { @@ -3135,7 +3132,7 @@ hypertext, nIndex); EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1); - PrintDebugString(" ##### hyperlink index = %d", index); + PrintDebugString("[INFO]: ##### hyperlink index = %d", index); return index; } @@ -3148,7 +3145,7 @@ const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)", hypertext, index); @@ -3161,7 +3158,7 @@ jobject globalRef = jniEnv->NewGlobalRef(hl); EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); info->accessibleHyperlink = (JOBJECT64)globalRef; - PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + PrintDebugString("[INFO]: ##### AccessibleHyperlink = %p", globalRef); // get the hyperlink text jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, @@ -3186,12 +3183,12 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleHyperlink text = %ls", info->text ); + PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", info->text ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleHyperlink text is null."); + PrintDebugString("[WARN]: AccessibleHyperlink text is null."); info->text[0] = (wchar_t) 0; } @@ -3200,14 +3197,14 @@ info->accessibleHyperlink, index); EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink start index = %d", info->startIndex); + PrintDebugString("[INFO]: ##### hyperlink start index = %d", info->startIndex); info->endIndex = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkEndIndexMethod, info->accessibleHyperlink, index); EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### hyperlink end index = %d", info->endIndex); + PrintDebugString("[INFO]: ##### hyperlink end index = %d", info->endIndex); return TRUE; } @@ -3221,7 +3218,7 @@ jthrowable exception; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)", accessibleContext, keyBindings); if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 || @@ -3236,7 +3233,7 @@ EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### key bindings count = %d", keyBindings->keyBindingsCount); + PrintDebugString("[INFO]: ##### key bindings count = %d", keyBindings->keyBindingsCount); // get the key bindings for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) { @@ -3247,8 +3244,9 @@ accessibleContext, i); EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE); - PrintDebugString(" ##### key binding character = %c", keyBindings->keyBindingInfo[i].character); - PrintDebugString(" ##### key binding character in hex = %hx", keyBindings->keyBindingInfo[i].character); + PrintDebugString("[INFO]: ##### key binding character = %c"\ + " ##### key binding character in hex = %hx"\ + , keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character); // get the key binding modifiers keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject, @@ -3256,7 +3254,7 @@ accessibleContext, i); EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers); + PrintDebugString("[INFO]: ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers); } return FALSE; } @@ -3269,14 +3267,14 @@ const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", accessibleContext, icons); if (getAccessibleIconsCountMethod == (jmethodID) 0 || getAccessibleIconDescriptionMethod == (jmethodID) 0 || getAccessibleIconHeightMethod == (jmethodID) 0 || getAccessibleIconWidthMethod == (jmethodID) 0) { - PrintDebugString(" ##### missing method(s) !!!"); + PrintDebugString("[WARN]: ##### missing method(s) !!!"); return FALSE; } @@ -3286,7 +3284,7 @@ getAccessibleIconsCountMethod, accessibleContext); EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### icons count = %d", icons->iconsCount); + PrintDebugString("[INFO]: ##### icons count = %d", icons->iconsCount); // get the icons @@ -3314,11 +3312,11 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleIcon description = %ls", icons->iconInfo[i].description ); + PrintDebugString("[INFO]: ##### AccessibleIcon description = %ls", icons->iconInfo[i].description ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleIcon description is null."); + PrintDebugString("[WARN]: AccessibleIcon description is null."); icons->iconInfo[i].description[0] = (wchar_t) 0; } @@ -3329,7 +3327,7 @@ accessibleContext, i); EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### icon height = %d", icons->iconInfo[i].height); + PrintDebugString("[INFO]: ##### icon height = %d", icons->iconInfo[i].height); // get the icon width icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject, @@ -3337,7 +3335,7 @@ accessibleContext, i); EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### icon width = %d", icons->iconInfo[i].width); + PrintDebugString("[INFO]: ##### icon width = %d", icons->iconInfo[i].width); } return FALSE; } @@ -3350,12 +3348,12 @@ const wchar_t *stringBytes; jsize length; - PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", accessibleContext, actions); if (getAccessibleActionsCountMethod == (jmethodID) 0 || getAccessibleActionNameMethod == (jmethodID) 0) { - PrintDebugString(" ##### missing method(s) !!!"); + PrintDebugString("[WARN]: ##### missing method(s) !!!"); return FALSE; } @@ -3365,7 +3363,7 @@ getAccessibleActionsCountMethod,accessibleContext); EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE); - PrintDebugString(" ##### key actions count = %d", actions->actionsCount); + PrintDebugString("[INFO]: ##### key actions count = %d", actions->actionsCount); // get the actions @@ -3393,11 +3391,11 @@ // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleAction name - call to CallVoidMethod()", FALSE); - PrintDebugString("##### AccessibleAction name = %ls", actions->actionInfo[i].name ); + PrintDebugString("[INFO]: ##### AccessibleAction name = %ls", actions->actionInfo[i].name ); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleAction name - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AccessibleAction name is null."); + PrintDebugString("[WARN]: AccessibleAction name is null."); actions->actionInfo[i].name [0] = (wchar_t) 0; } } @@ -3411,7 +3409,7 @@ jthrowable exception; BOOL returnVal; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):", accessibleContext, actionsToDo->actionsCount, actionsToDo->actions[0].name); @@ -3421,15 +3419,15 @@ return FALSE; } - PrintDebugString("\r\n doing %d actions ...", actionsToDo->actionsCount); + PrintDebugString("[INFO]: doing %d actions ...", actionsToDo->actionsCount); for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) { - PrintDebugString("\r doing action %d: %s ...", i, actionsToDo->actions[i].name); + PrintDebugString("[INFO]: doing action %d: %s ...", i, actionsToDo->actions[i].name); // create a Java String for the action name wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name; jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName)); if (javaName == 0) { - PrintDebugString("\r NewString failed"); + PrintDebugString("[ERROR]: NewString failed"); *failure = i; return FALSE; } @@ -3440,7 +3438,7 @@ EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE); if (returnVal != TRUE) { - PrintDebugString("\r Action %d failed", i); + PrintDebugString("[ERROR]: Action %d failed", i); *failure = i; return FALSE; } @@ -3464,7 +3462,7 @@ return FALSE; } - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):", accessibleContext, x, y); // Get the character count @@ -3473,9 +3471,9 @@ getAccessibleCharCountFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE); - PrintDebugString(" Char count = %d", textInfo->charCount); + PrintDebugString("[INFO]: Char count = %d", textInfo->charCount); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleCharCountFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleCharCountFromContextMethod == 0"); return FALSE; } @@ -3485,9 +3483,9 @@ getAccessibleCaretPositionFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE); - PrintDebugString(" Index at caret = %d", textInfo->caretIndex); + PrintDebugString("[INFO]: Index at caret = %d", textInfo->caretIndex); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleCaretPositionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleCaretPositionFromContextMethod == 0"); return FALSE; } @@ -3497,9 +3495,9 @@ getAccessibleIndexAtPointFromContextMethod, accessibleContext, x, y); EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE); - PrintDebugString(" Index at point = %d", textInfo->indexAtPoint); + PrintDebugString("[INFO]: Index at point = %d", textInfo->indexAtPoint); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0"); + PrintDebugString("[ERROR]: Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0"); return FALSE; } return TRUE; @@ -3513,7 +3511,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext); // Verify the Java VM still exists and AccessibleContext is // an instance of AccessibleText @@ -3527,7 +3525,7 @@ getAccessibleLetterAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE); @@ -3537,15 +3535,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE); - PrintDebugString(" Accessible Text letter = %c", textItems->letter); + PrintDebugString("[INFO]: Accessible Text letter = %c", textItems->letter); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Text letter is null."); + PrintDebugString("[WARN]: Accessible Text letter is null."); textItems->letter = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0"); return FALSE; } @@ -3556,7 +3554,7 @@ getAccessibleWordAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE); @@ -3570,15 +3568,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Text word = %ls", textItems->word); + wPrintDebugString(L"[INFO]: Accessible Text word = %ls", textItems->word); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Text word is null."); + PrintDebugString("[WARN]: Accessible Text word is null."); textItems->word[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0"); return FALSE; } @@ -3588,7 +3586,7 @@ getAccessibleSentenceAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE); @@ -3606,15 +3604,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Text sentence = %ls", textItems->sentence); + wPrintDebugString(L"[INFO]: Accessible Text sentence = %ls", textItems->sentence); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Text sentence is null."); + PrintDebugString("[WARN]: Accessible Text sentence is null."); textItems->sentence[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0"); return FALSE; } @@ -3629,7 +3627,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):", accessibleContext); // Verify the Java VM still exists and AccessibleContext is @@ -3644,9 +3642,9 @@ getAccessibleTextSelectionStartFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE); - PrintDebugString(" Selection start = %d", selectionInfo->selectionStartIndex); + PrintDebugString("[INFO]: Selection start = %d", selectionInfo->selectionStartIndex); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0"); return FALSE; } @@ -3656,9 +3654,9 @@ getAccessibleTextSelectionEndFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE); - PrintDebugString(" Selection end = %d", selectionInfo->selectionEndIndex); + PrintDebugString("[INFO]: Selection end = %d", selectionInfo->selectionEndIndex); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0"); return FALSE; } @@ -3668,7 +3666,7 @@ getAccessibleTextSelectedTextFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE); @@ -3682,15 +3680,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE); - PrintDebugString(" Accessible's selected text = %s", selectionInfo->selectedText); + PrintDebugString("[INFO]: Accessible's selected text = %s", selectionInfo->selectedText); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible's selected text is null."); + PrintDebugString("[WARN]: Accessible's selected text is null."); selectionInfo->selectedText[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0"); + PrintDebugString("[WARN]: either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0"); return FALSE; } return TRUE; @@ -3704,7 +3702,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext); // Verify the Java VM still exists and AccessibleContext is // an instance of AccessibleText @@ -3713,7 +3711,7 @@ } if (accessibleContext == (jobject) 0) { - PrintDebugString(" passed in AccessibleContext == null! (oops)"); + PrintDebugString("[WARN]: passed in AccessibleContext == null! (oops)"); attributes->bold = FALSE; attributes->italic = FALSE; @@ -3740,19 +3738,19 @@ // Get the AttributeSet if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) { - PrintDebugString(" Getting AttributeSet at index..."); + PrintDebugString("[INFO]: Getting AttributeSet at index..."); AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleAttributeSetAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0"); return FALSE; } // It is legal for the AttributeSet object to be null, in which case we return false! if (AttributeSet == (jobject) 0) { - PrintDebugString(" AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3"); + PrintDebugString("[WARN]: AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3"); attributes->bold = FALSE; attributes->italic = FALSE; @@ -3779,13 +3777,13 @@ // Get the bold setting if (getBoldFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting bold from AttributeSet..."); + PrintDebugString("[INFO]: Getting bold from AttributeSet..."); attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getBoldFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getBoldFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getBoldFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3796,13 +3794,13 @@ // Get the italic setting if (getItalicFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting italic from AttributeSet..."); + PrintDebugString("[INFO]: Getting italic from AttributeSet..."); attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getItalicFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getItalicdFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getItalicdFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3813,13 +3811,13 @@ // Get the underline setting if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting underline from AttributeSet..."); + PrintDebugString("[INFO]: Getting underline from AttributeSet..."); attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getUnderlineFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getUnderlineFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getUnderlineFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3830,13 +3828,13 @@ // Get the strikethrough setting if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting strikethrough from AttributeSet..."); + PrintDebugString("[INFO]: Getting strikethrough from AttributeSet..."); attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getStrikethroughFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getStrikethroughFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getStrikethroughFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3847,13 +3845,13 @@ // Get the superscript setting if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting superscript from AttributeSet..."); + PrintDebugString("[INFO]: Getting superscript from AttributeSet..."); attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getSuperscriptFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getSuperscripteFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getSuperscripteFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3864,13 +3862,13 @@ // Get the subscript setting if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting subscript from AttributeSet..."); + PrintDebugString("[INFO]: Getting subscript from AttributeSet..."); attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, getSubscriptFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getSubscriptFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getSubscriptFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3881,7 +3879,7 @@ // Get the backgroundColor setting if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting backgroundColor from AttributeSet..."); + PrintDebugString("[INFO]: Getting backgroundColor from AttributeSet..."); js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getBackgroundColorFromAttributeSetMethod, AttributeSet); @@ -3899,15 +3897,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" AttributeSet's background color = %ls", attributes->backgroundColor); + wPrintDebugString(L"[INFO]: AttributeSet's background color = %ls", attributes->backgroundColor); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AttributeSet's background color is null."); + PrintDebugString("[WARN]: AttributeSet's background color is null."); attributes->backgroundColor[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getBackgroundColorFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getBackgroundColorFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3918,7 +3916,7 @@ // Get the foregroundColor setting if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting foregroundColor from AttributeSet..."); + PrintDebugString("[INFO]: Getting foregroundColor from AttributeSet..."); js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getForegroundColorFromAttributeSetMethod, AttributeSet); @@ -3936,15 +3934,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" AttributeSet's foreground color = %ls", attributes->foregroundColor); + wPrintDebugString(L"[INFO]: AttributeSet's foreground color = %ls", attributes->foregroundColor); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AttributeSet's foreground color is null."); + PrintDebugString("[WARN]: AttributeSet's foreground color is null."); attributes->foregroundColor[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getForegroundColorFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getForegroundColorFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3955,7 +3953,7 @@ // Get the fontFamily setting if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting fontFamily from AttributeSet..."); + PrintDebugString("[INFO]: Getting fontFamily from AttributeSet..."); js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getFontFamilyFromAttributeSetMethod, AttributeSet); @@ -3973,15 +3971,15 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" AttributeSet's fontFamily = %ls", attributes->fontFamily); + wPrintDebugString(L"[INFO]: AttributeSet's fontFamily = %ls", attributes->fontFamily); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" AttributeSet's fontFamily is null."); + PrintDebugString("[WARN]: AttributeSet's fontFamily is null."); attributes->backgroundColor[0] = (wchar_t) 0; } } else { - PrintDebugString(" Error! either env == 0 or getFontFamilyFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getFontFamilyFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3992,14 +3990,14 @@ // Get the font size if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting font size from AttributeSet..."); + PrintDebugString("[INFO]: Getting font size from AttributeSet..."); attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject, getFontSizeFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE); - PrintDebugString(" AttributeSet's font size = %d", attributes->fontSize); + PrintDebugString("[INFO]: AttributeSet's font size = %d", attributes->fontSize); } else { - PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4011,13 +4009,13 @@ // Get the alignment setting if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting alignment from AttributeSet..."); + PrintDebugString("[INFO]: Getting alignment from AttributeSet..."); attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject, getAlignmentFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4028,13 +4026,13 @@ // Get the bidiLevel setting if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting bidiLevel from AttributeSet..."); + PrintDebugString("[INFO]: Getting bidiLevel from AttributeSet..."); attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject, getBidiLevelFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getBidiLevelFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getBidiLevelFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4045,13 +4043,13 @@ // Get the firstLineIndent setting if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting firstLineIndent from AttributeSet..."); + PrintDebugString("[ERROR]: Getting firstLineIndent from AttributeSet..."); attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getFirstLineIndentFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4062,13 +4060,13 @@ // Get the leftIndent setting if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting leftIndent from AttributeSet..."); + PrintDebugString("[INFO]: Getting leftIndent from AttributeSet..."); attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getLeftIndentFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getLeftIndentFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getLeftIndentFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4079,13 +4077,13 @@ // Get the rightIndent setting if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting rightIndent from AttributeSet..."); + PrintDebugString("[INFO]: Getting rightIndent from AttributeSet..."); attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getRightIndentFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getRightIndentFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getRightIndentFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4096,13 +4094,13 @@ // Get the lineSpacing setting if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting lineSpacing from AttributeSet..."); + PrintDebugString("[INFO]: Getting lineSpacing from AttributeSet..."); attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getLineSpacingFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getLineSpacingFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getLineSpacingFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4113,13 +4111,13 @@ // Get the spaceAbove setting if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting spaceAbove from AttributeSet..."); + PrintDebugString("[INFO]: Getting spaceAbove from AttributeSet..."); attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getSpaceAboveFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getSpaceAboveFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getSpaceAboveFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4130,13 +4128,13 @@ // Get the spaceBelow setting if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) { - PrintDebugString(" Getting spaceBelow from AttributeSet..."); + PrintDebugString("[INFO]: Getting spaceBelow from AttributeSet..."); attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, getSpaceBelowFromAttributeSetMethod, AttributeSet); EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or getSpaceBelowFromAttributeSetMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getSpaceBelowFromAttributeSetMethod == 0"); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4147,12 +4145,12 @@ // Release the AttributeSet object if (decrementReferenceMethod != (jmethodID) 0) { - PrintDebugString(" Decrementing reference to AttributeSet..."); + PrintDebugString("[INFO]: Decrementing reference to AttributeSet..."); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, AttributeSet); EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or accessBridgeObject == 0"); + PrintDebugString("[ERROR]: either env == 0 or accessBridgeObject == 0"); jniEnv->DeleteLocalRef(AttributeSet); EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE); return FALSE; @@ -4160,12 +4158,12 @@ // Get the full attributes string at index if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { - PrintDebugString(" Getting full attributes string from Context..."); + PrintDebugString("[INFO]: Getting full attributes string from Context..."); js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleAttributesAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); @@ -4179,18 +4177,18 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Text attributes = %ls", attributes->fullAttributesString); + wPrintDebugString(L"[INFO]: Accessible Text attributes = %ls", attributes->fullAttributesString); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" Accessible Text attributes is null."); + PrintDebugString("[WARN]: Accessible Text attributes is null."); attributes->fullAttributesString[0] = (wchar_t) 0; jniEnv->DeleteLocalRef(AttributeSet); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); jniEnv->DeleteLocalRef(AttributeSet); return FALSE; } @@ -4205,7 +4203,7 @@ jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d", accessibleContext, index); // Verify the Java VM still exists and AccessibleContext is @@ -4220,9 +4218,9 @@ getAccessibleXcoordTextRectAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE); - PrintDebugString(" X coord = %d", rectInfo->x); + PrintDebugString("[INFO]: X coord = %d", rectInfo->x); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0"); return FALSE; } @@ -4232,9 +4230,9 @@ getAccessibleYcoordTextRectAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE); - PrintDebugString(" Y coord = %d", rectInfo->y); + PrintDebugString("[INFO]: Y coord = %d", rectInfo->y); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0"); + PrintDebugString("[INFO]: either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0"); return FALSE; } @@ -4244,9 +4242,9 @@ getAccessibleWidthTextRectAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE); - PrintDebugString(" Width = %d", rectInfo->width); + PrintDebugString("[INFO]: Width = %d", rectInfo->width); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0"); + PrintDebugString("[INFO]: either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0"); return FALSE; } @@ -4256,9 +4254,9 @@ getAccessibleHeightTextRectAtIndexFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE); - PrintDebugString(" Height = %d", rectInfo->height); + PrintDebugString("[INFO]: Height = %d", rectInfo->height); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0"); return FALSE; } @@ -4275,7 +4273,7 @@ jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d", + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d", accessibleContext, index); // Verify the Java VM still exists and AccessibleContext is @@ -4290,9 +4288,9 @@ getCaretLocationXMethod, accessibleContext, index); EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE); - PrintDebugString(" X coord = %d", rectInfo->x); + PrintDebugString("[INFO]: X coord = %d", rectInfo->x); } else { - PrintDebugString(" Error! either env == 0 or getCaretLocationXMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getCaretLocationXMethod == 0"); return FALSE; } @@ -4302,9 +4300,9 @@ getCaretLocationYMethod, accessibleContext, index); EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE); - PrintDebugString(" Y coord = %d", rectInfo->y); + PrintDebugString("[INFO]: Y coord = %d", rectInfo->y); } else { - PrintDebugString(" Error! either env == 0 or getCaretLocationYMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getCaretLocationYMethod == 0"); return FALSE; } @@ -4314,9 +4312,9 @@ getCaretLocationWidthMethod, accessibleContext, index); EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE); - PrintDebugString(" Width = %d", rectInfo->width); + PrintDebugString("[INFO]: Width = %d", rectInfo->width); } else { - PrintDebugString(" Error! either env == 0 or getCaretLocationWidthMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getCaretLocationWidthMethod == 0"); return FALSE; } @@ -4326,9 +4324,9 @@ getCaretLocationHeightMethod, accessibleContext, index); EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE); - PrintDebugString(" Height = %d", rectInfo->height); + PrintDebugString("[INFO]: Height = %d", rectInfo->height); } else { - PrintDebugString(" Error! either env == 0 or getCaretLocationHeightMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getCaretLocationHeightMethod == 0"); return FALSE; } @@ -4342,7 +4340,7 @@ jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext); // Verify the Java VM still exists and AccessibleContext is // an instance of AccessibleText @@ -4356,9 +4354,9 @@ getAccessibleTextLineLeftBoundsFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE); - PrintDebugString(" startIndex = %d", *startIndex); + PrintDebugString("[INFO]: startIndex = %d", *startIndex); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0"); return FALSE; } @@ -4368,9 +4366,9 @@ getAccessibleTextLineRightBoundsFromContextMethod, accessibleContext, index); EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE); - PrintDebugString(" endIndex = %d", *endIndex); + PrintDebugString("[INFO]: endIndex = %d", *endIndex); } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0"); return FALSE; } @@ -4385,7 +4383,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len); // Verify the Java VM still exists and AccessibleContext is // an instance of AccessibleText @@ -4395,7 +4393,7 @@ // range is inclusive if (end < start) { - PrintDebugString(" Error! end < start!"); + PrintDebugString("[ERROR]: end < start!"); text[0] = (wchar_t) 0; return FALSE; } @@ -4406,32 +4404,32 @@ getAccessibleTextRangeFromContextMethod, accessibleContext, start, end); EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE); - wPrintDebugString(L" Accessible Text stringBytes returned from Java = %ls", stringBytes); + wPrintDebugString(L"[INFO]: Accessible Text stringBytes returned from Java = %ls", stringBytes); wcsncpy(text, stringBytes, len); length = jniEnv->GetStringLength(js); - PrintDebugString(" Accessible Text stringBytes length = %d", length); + PrintDebugString("[INFO]: Accessible Text stringBytes length = %d", length); text[length < len ? length : len - 2] = (wchar_t) 0; - wPrintDebugString(L" Accessible Text 'text' after null termination = %ls", text); + wPrintDebugString(L"[INFO]: Accessible Text 'text' after null termination = %ls", text); EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE); jniEnv->ReleaseStringChars(js, stringBytes); EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE); - wPrintDebugString(L" Accessible Text range = %ls", text); + wPrintDebugString(L"[INFO]: Accessible Text range = %ls", text); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" current Accessible Text range is null."); + PrintDebugString("[WARN]: current Accessible Text range is null."); text[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getAccessibleTextRangeFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextRangeFromContextMethod == 0"); return FALSE; } return TRUE; @@ -4446,7 +4444,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext); // Get the current Accessible Value if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) { @@ -4454,7 +4452,7 @@ getCurrentAccessibleValueFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE); @@ -4467,16 +4465,16 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE); - PrintDebugString(" current Accessible Value = %s", value); + PrintDebugString("[INFO]: current Accessible Value = %s", value); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" current Accessible Value is null."); + PrintDebugString("[WARN]: current Accessible Value is null."); value[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getCurrentAccessibleValueFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getCurrentAccessibleValueFromContextMethod == 0"); return FALSE; } return TRUE; @@ -4489,7 +4487,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext); // Get the maximum Accessible Value if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) { @@ -4497,7 +4495,7 @@ getMaximumAccessibleValueFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE); @@ -4510,16 +4508,16 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE); - PrintDebugString(" maximum Accessible Value = %s", value); + PrintDebugString("[INFO]: maximum Accessible Value = %s", value); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" maximum Accessible Value is null."); + PrintDebugString("[WARN]: maximum Accessible Value is null."); value[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getMaximumAccessibleValueFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getMaximumAccessibleValueFromContextMethod == 0"); return FALSE; } return TRUE; @@ -4532,7 +4530,7 @@ jthrowable exception; jsize length; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext); // Get the mimimum Accessible Value if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) { @@ -4540,7 +4538,7 @@ getMinimumAccessibleValueFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + PrintDebugString("[INFO]: returned from CallObjectMethod(), js = %p", js); if (js != (jstring) 0) { stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE); @@ -4553,16 +4551,16 @@ jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE); - PrintDebugString(" mimimum Accessible Value = %s", value); + PrintDebugString("[INFO]: mimimum Accessible Value = %s", value); jniEnv->DeleteLocalRef(js); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE); } else { - PrintDebugString(" mimimum Accessible Value is null."); + PrintDebugString("[WARN]: mimimum Accessible Value is null."); value[0] = (wchar_t) 0; return FALSE; } } else { - PrintDebugString(" Error! either env == 0 or getMinimumAccessibleValueFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getMinimumAccessibleValueFromContextMethod == 0"); return FALSE; } return TRUE; @@ -4575,7 +4573,7 @@ AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) { jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext); // Add the child to the AccessibleSelection if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) { @@ -4583,9 +4581,9 @@ addAccessibleSelectionFromContextMethod, accessibleContext, i); EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()"); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); } else { - PrintDebugString(" Error! either env == 0 or addAccessibleSelectionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or addAccessibleSelectionFromContextMethod == 0"); } } @@ -4593,7 +4591,7 @@ AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) { jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext); // Clearing the Selection of the AccessibleSelection if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) { @@ -4601,9 +4599,9 @@ clearAccessibleSelectionFromContextMethod, accessibleContext); EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()"); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); } else { - PrintDebugString(" Error! either env == 0 or clearAccessibleSelectionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or clearAccessibleSelectionFromContextMethod == 0"); } } @@ -4613,7 +4611,7 @@ jobject globalRef; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext); if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) { returnedAccessibleContext = jniEnv->CallObjectMethod( @@ -4625,11 +4623,11 @@ EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0); jniEnv->DeleteLocalRef(returnedAccessibleContext); EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0); - PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + PrintDebugString("[INFO]: Returning - returnedAccessibleContext = %p; globalRef = %p", returnedAccessibleContext, globalRef); return globalRef; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleSelectionContextFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionContextFromContextMethod == 0"); return (jobject) 0; } } @@ -4639,7 +4637,7 @@ int count; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext); // Get (& return) the # of items selected in the AccessibleSelection if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) { @@ -4647,10 +4645,10 @@ getAccessibleSelectionCountFromContextMethod, accessibleContext); EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); return count; } else { - PrintDebugString(" Error! either env == 0 or getAccessibleSelectionCountFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionCountFromContextMethod == 0"); return -1; } } @@ -4660,7 +4658,7 @@ jboolean result; jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext); // Get (& return) the # of items selected in the AccessibleSelection if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) { @@ -4668,12 +4666,12 @@ isAccessibleChildSelectedFromContextMethod, accessibleContext, i); EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); if (result != 0) { return TRUE; } } else { - PrintDebugString(" Error! either env == 0 or isAccessibleChildSelectedFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or isAccessibleChildSelectedFromContextMethod == 0"); } return FALSE; } @@ -4683,7 +4681,7 @@ AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) { jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext); // Remove the i-th child from the AccessibleSelection if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) { @@ -4691,9 +4689,9 @@ removeAccessibleSelectionFromContextMethod, accessibleContext, i); EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()"); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); } else { - PrintDebugString(" Error! either env == 0 or removeAccessibleSelectionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or removeAccessibleSelectionFromContextMethod == 0"); } } @@ -4701,7 +4699,7 @@ AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) { jthrowable exception; - PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext); + PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext); // Select all children (if possible) of the AccessibleSelection if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) { @@ -4709,9 +4707,9 @@ selectAllAccessibleSelectionFromContextMethod, accessibleContext); EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()"); - PrintDebugString(" returned from CallObjectMethod()"); + PrintDebugString("[INFO]: returned from CallObjectMethod()"); } else { - PrintDebugString(" Error! either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0"); } } @@ -4722,7 +4720,7 @@ AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) { jthrowable exception; - PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type); + PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type); // Let AccessBridge know we want to add an event type if (addJavaEventNotificationMethod != (jmethodID) 0) { @@ -4730,7 +4728,7 @@ addJavaEventNotificationMethod, type); EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or addJavaEventNotificationMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or addJavaEventNotificationMethod == 0"); return FALSE; } return TRUE; @@ -4740,7 +4738,7 @@ AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) { jthrowable exception; - PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type); + PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type); // Let AccessBridge know we want to remove an event type if (removeJavaEventNotificationMethod != (jmethodID) 0) { @@ -4748,7 +4746,7 @@ removeJavaEventNotificationMethod, type); EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or removeJavaEventNotificationMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or removeJavaEventNotificationMethod == 0"); return FALSE; } return TRUE; @@ -4758,19 +4756,19 @@ AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) { jthrowable exception; - PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type); + PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type); // Let AccessBridge know we want to add an event type if (addAccessibilityEventNotificationMethod != (jmethodID) 0) { - PrintDebugString("\r\n addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject); + PrintDebugString("[INFO]: addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject); jniEnv->CallVoidMethod(accessBridgeObject, addAccessibilityEventNotificationMethod, type); EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or addAccessibilityEventNotificationMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or addAccessibilityEventNotificationMethod == 0"); return FALSE; } - PrintDebugString("\r\n addAccessibilityEventNotification: just returning true"); + PrintDebugString("[INFO]: addAccessibilityEventNotification: just returning true"); return TRUE; } @@ -4778,7 +4776,7 @@ AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) { jthrowable exception; - PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type); + PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type); // Let AccessBridge know we want to remove an event type if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) { @@ -4786,7 +4784,7 @@ removeAccessibilityEventNotificationMethod, type); EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE); } else { - PrintDebugString(" Error! either env == 0 or removeAccessibilityEventNotificationMethod == 0"); + PrintDebugString("[ERROR]: either env == 0 or removeAccessibilityEventNotificationMethod == 0"); return FALSE; } return TRUE; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -188,7 +188,7 @@ * with the Java AccessBridge DLL * * NOTE: WM_COPYDATA is only for one-way IPC; there - * is now way to return parameters (especially big ones) + * is no way to return parameters (especially big ones) * Use sendMemoryPackage() to do that! */ LRESULT @@ -198,8 +198,8 @@ toCopy.cbData = bufsize; toCopy.lpData = buffer; - PrintDebugString("In AccessBridgeVMInstance::sendPackage"); - PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + PrintDebugString("[INFO]: In AccessBridgeVMInstance::sendPackage"); + PrintDebugString("[INFO]: javaAccessBridgeWindow: %p", javaAccessBridgeWindow); /* This was SendMessage. Normally that is a blocking call. However, if * SendMessage is sent to another process, e.g. another JVM and an incoming * SendMessage is pending, control will be passed to the DialogProc to handle @@ -280,7 +280,7 @@ char *done = &memoryMappedView[bufsize]; *done = 0; - PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + PrintDebugString("[INFO]: javaAccessBridgeWindow: %p", javaAccessBridgeWindow); // See the comment above the call to SendMessageTimeout in SendPackage method above. UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; DWORD_PTR out; // not used @@ -309,7 +309,7 @@ */ HWND AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) { - PrintDebugString("In findAccessBridgeWindow"); + PrintDebugString("[INFO]: In findAccessBridgeWindow"); // no need to recurse really if (vmID == javaVMID) { return javaAccessBridgeWindow; @@ -338,7 +338,7 @@ */ AccessBridgeJavaVMInstance * AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) { - PrintDebugString("In findABJavaInstanceFromJavaHWND"); + PrintDebugString("[INFO]: In findABJavaInstanceFromJavaHWND"); // no need to recurse really if (javaAccessBridgeWindow == window) { return this; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -88,17 +88,17 @@ */ QueueReturns AccessBridgeMessageQueue::add(AccessBridgeQueueElement *element) { - PrintDebugString(" in AccessBridgeMessageQueue::add()"); - PrintDebugString(" queue size = %d", size); + PrintDebugString("[INFO]: in AccessBridgeMessageQueue::add()"); + PrintDebugString("[INFO]: queue size = %d", size); QueueReturns returnVal = cElementPushedOK; if (queueLocked) { - PrintDebugString(" queue was locked; returning cQueueInUse!"); + PrintDebugString("[WARN]: queue was locked; returning cQueueInUse!"); return cQueueInUse; } queueLocked = TRUE; { - PrintDebugString(" adding element to queue!"); + PrintDebugString("[INFO]: adding element to queue!"); if (end == (AccessBridgeQueueElement *) 0) { if (start == (AccessBridgeQueueElement *) 0 && size == 0) { start = element; @@ -118,7 +118,7 @@ } } queueLocked = FALSE; - PrintDebugString(" returning from AccessBridgeMessageQueue::add()"); + PrintDebugString("[INFO]: returning from AccessBridgeMessageQueue::add()"); return returnVal; } @@ -129,17 +129,17 @@ */ QueueReturns AccessBridgeMessageQueue::remove(AccessBridgeQueueElement **element) { - PrintDebugString(" in AccessBridgeMessageQueue::remove()"); - PrintDebugString(" queue size = %d", size); + PrintDebugString("[INFO]: in AccessBridgeMessageQueue::remove()"); + PrintDebugString("[INFO]: queue size = %d", size); QueueReturns returnVal = cMoreMessages; if (queueLocked) { - PrintDebugString(" queue was locked; returning cQueueInUse!"); + PrintDebugString("[WARN]: queue was locked; returning cQueueInUse!"); return cQueueInUse; } queueLocked = TRUE; { - PrintDebugString(" removing element from queue!"); + PrintDebugString("[INFO]: removing element from queue!"); if (size > 0) { if (start != (AccessBridgeQueueElement *) 0) { *element = start; @@ -161,7 +161,7 @@ } } queueLocked = FALSE; - PrintDebugString(" returning from AccessBridgeMessageQueue::remove()"); + PrintDebugString("[INFO]: returning from AccessBridgeMessageQueue::remove()"); return returnVal; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -51,7 +51,6 @@ // open our window if (theWindowsAccessBridge != (WinAccessBridge *) 0) { theWindowsAccessBridge->initWindow(); - DEBUG_CODE(SetDlgItemText(theDialogWindow, cInvokedByText, "Windows")); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,57 +87,35 @@ */ JNIEXPORT void JNICALL Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) { - PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called"); + PrintDebugString("[INFO]: JavaAccessBridge.DLL runDLL() called"); theJavaAccessBridge->javaRun(env, obj); } -#if 0 // SetDlgItemText has caused problems with JAWS - /** - * Append debug info to dialog - * - */ - void AppendToCallInfo(char *s) { - char buffer[4096]; - - PrintDebugString(s); - - GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer)); - if (strlen(buffer) < (sizeof(buffer) - strlen(s))) { - strncat(buffer, s, sizeof(buffer)); - SetDlgItemText(theDialogWindow, cCallInfo, buffer); - } else { - SetDlgItemText(theDialogWindow, cCallInfo, s); - } - } -#endif - - /** * Our window proc * */ - BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) { + BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int command; COPYDATASTRUCT *sentToUs; char *package; - //DEBUG_CODE(char buffer[256]); switch (message) { case WM_INITDIALOG: - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Initializing")); + PrintDebugString("[INFO]: In AccessBridgeDialog - Initializing"); break; case WM_COMMAND: command = LOWORD (wParam); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COMMAND, command: %X", command); break; // call from Java with data for us to deliver case WM_COPYDATA: if (theDialogWindow == (HWND) wParam) { - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves")); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COPYDATA from ourselves"); } else { - //DEBUG_CODE(sprintf(buffer, "Got WM_COPYDATA from HWND %p", wParam)); - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COPYDATA from HWND %p", wParam); sentToUs = (COPYDATASTRUCT *) lParam; package = (char *) sentToUs->lpData; theJavaAccessBridge->processPackage(package, sentToUs->cbData); @@ -149,18 +127,16 @@ // wParam == sourceHwnd // lParam == buffer size in shared memory if (theDialogWindow == (HWND) wParam) { - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves")); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_MESSAGE_WAITING from ourselves"); } else { - //DEBUG_CODE(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %p", wParam)); - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); - LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_MESSAGE_WAITING from HWND %p", wParam); + LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, (long) lParam); } break; // a JavaAccessBridge DLL is going away case AB_DLL_GOING_AWAY: - // wParam == sourceHwnd - //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message")); + PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_DLL_GOING_AWAY message"); theJavaAccessBridge->WindowsATDestroyed((HWND) wParam); break; @@ -171,6 +147,7 @@ // A new Windows AT just said "hi"; // say "hi" back so it can mate up with us // otherwise don't do anything (e.g. don't set up data structures yet) + PrintDebugString("[INFO]: In AccessBridgeDialog - Got theFromWindowsHelloMsgID message"); theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam); } } @@ -190,6 +167,7 @@ JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) { windowsInstance = hInstance; ATs = (AccessBridgeATInstance *) 0; + initializeFileLogger("java_access_bridge"); initBroadcastMessageIDs(); // get the unique to us broadcast msg. IDs } @@ -202,7 +180,7 @@ JavaAccessBridge::~JavaAccessBridge() { // inform all other AccessBridges that we're going away - PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()"); + PrintDebugString("[INFO]: in JavaAccessBridge::~JavaAccessBridge()"); // Send a shutdown message for those applications like StarOffice that do // send a shutdown message themselves. @@ -210,13 +188,13 @@ AccessBridgeATInstance *current = ATs; while (current != (AccessBridgeATInstance *) 0) { - PrintDebugString(" telling %p we're going away", current->winAccessBridgeWindow); + PrintDebugString("[INFO]: telling %p we're going away", current->winAccessBridgeWindow); SendMessage(current->winAccessBridgeWindow, AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); current = current->nextATInstance; } - PrintDebugString(" finished telling ATs about our demise"); + PrintDebugString("[INFO]: finished telling ATs about our demise"); if(JavaBridgeThreadId) { @@ -226,8 +204,9 @@ delete ATs; - PrintDebugString(" finished deleting ATs"); - PrintDebugString("GOODBYE CRUEL WORLD..."); + PrintDebugString("[INFO]: finished deleting ATs"); + PrintDebugString("[INFO]: GOODBYE CRUEL WORLD..."); + finalizeFileLogger(); } @@ -235,17 +214,17 @@ JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) { MSG msg; - PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj); + PrintDebugString("[INFO]: JavaAccessBridge::javaRun(%p, %p) called", env, obj); if (env->GetJavaVM(&javaVM) != 0) { return; // huh!?!?! } - PrintDebugString(" -> javaVM = %p", javaVM); + PrintDebugString("[INFO]: -> javaVM = %p", javaVM); if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) { return; // huh!?!?! } - PrintDebugString(" -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv); + PrintDebugString("[INFO]: -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv); javaThreadABObject = env->NewGlobalRef(obj); windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj); @@ -255,7 +234,7 @@ if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { return; // couldn't build our entry points; let's get out of here! } - PrintDebugString(" all Java thread entry points successfully found."); + PrintDebugString("[INFO]: all Java thread entry points successfully found."); // initialize the Windows thread AccessBridge entry points windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv, @@ -263,12 +242,12 @@ if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { return; // couldn't build our entry points; let's get out of here! } - PrintDebugString(" all Windows thread entry points successfully found."); + PrintDebugString("[INFO]: all Windows thread entry points successfully found."); // open our window if (initWindow() == TRUE) { - PrintDebugString(" Window created. HWND = %p", dialogWindow); + PrintDebugString("[INFO]: Window created. HWND = %p", dialogWindow); // post a broadcast msg.; let other AccessBridge DLLs know we exist postHelloToWindowsDLLMsg(HWND_BROADCAST); @@ -279,7 +258,7 @@ DispatchMessage(&msg); } } else { - PrintDebugString(" FAILED TO CREATE WINDOW!!!"); + PrintDebugString("[ERROR]: FAILED TO CREATE WINDOW!!!"); } javaVM->DetachCurrentThread(); @@ -326,9 +305,9 @@ */ void JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) { - PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg"); - PrintDebugString(" calling PostMessage(%p, %X, %p, %p)", - destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM); + PrintDebugString("[INFO]: In JavaAccessBridge::postHelloToWindowsDLLMsg"); + PrintDebugString("[INFO]: calling PostMessage(%p, %X, %p, %p)", + destHwnd, theFromJavaHelloMsgID, dialogWindow, dialogWindow); PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow); } @@ -358,10 +337,10 @@ void JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) { - PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type); + PrintDebugString("[INFO]: JavaAccessBridge::sendJavaEventPackage(), type = %X", type); if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); } AccessBridgeATInstance *ati = ATs; @@ -378,10 +357,10 @@ void JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) { - PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type); + PrintDebugString("[INFO]: JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type); if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR] ATs == 0! (shouldn't happen here!)"); } AccessBridgeATInstance *ati = ATs; @@ -406,11 +385,11 @@ JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) { char *IPCview; - PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize); + PrintDebugString("[INFO]: JavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize); // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!"); + PrintDebugString("[ERROR]: - ATs == 0 (shouldn't happen in receiveMemoryPackage()!"); return FALSE; } AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow); @@ -433,7 +412,7 @@ } else { //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow")); - PrintDebugString("ERROR receiving memory package: couldn't find srcWindow"); + PrintDebugString("[ERROR]: receiving memory package: couldn't find srcWindow"); return FALSE; } } @@ -445,11 +424,11 @@ */ LRESULT JavaAccessBridge::processPackage(char *buffer, int bufsize) { - PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize); + PrintDebugString("[INFO]: Processing package sent from Windows, bufsize = %d:", bufsize); PackageType *type = (PackageType *) buffer; LRESULT returnVal = 0; - PrintDebugString(" PackageType = %X:", *type); + PrintDebugString("[INFO]: PackageType = %X:", *type); jobject rAC; switch (*type) { @@ -458,13 +437,13 @@ case cMemoryMappedFileCreatedPackage: // Windows is telling us it created a memory mapped file for us to use // in repsonding to various information querying packages (see below) - PrintDebugString(" type == cMemoryMappedFileCreatedPackage"); + PrintDebugString("[INFO]: type == cMemoryMappedFileCreatedPackage"); if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) { MemoryMappedFileCreatedPackage *pkg = (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType)); returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)); } break; @@ -472,84 +451,84 @@ // ------------ information querying packages ------------------ case cReleaseJavaObjectPackage: - PrintDebugString(" type == cReleaseJavaObjectPackage"); + PrintDebugString("[INFO]: type == cReleaseJavaObjectPackage"); if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) { ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType)); releaseJavaObject((jobject)pkg->object); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)); } break; case cGetAccessBridgeVersionPackage: - PrintDebugString(" type == cGetAccessBridgeVersionPackage"); + PrintDebugString("[INFO]: type == cGetAccessBridgeVersionPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) { GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)); } break; case cIsJavaWindowPackage: - PrintDebugString(" type == cIsJavaWindowPackage"); + PrintDebugString("[INFO]: type == cIsJavaWindowPackage"); if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) { IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->isJavaWindow(pkg->window); - PrintDebugString(" -> returning result = %d", pkg->rResult); + PrintDebugString("[INFO]: -> returning result = %d", pkg->rResult); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage)); } break; case cIsSameObjectPackage: - PrintDebugString(" type == cIsSameObjectPackage"); + PrintDebugString("[INFO]: type == cIsSameObjectPackage"); if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) { IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2); - PrintDebugString(" -> returning result = %d", pkg->rResult); + PrintDebugString("[INFO]: -> returning result = %d", pkg->rResult); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage)); } break; case cGetAccessibleContextFromHWNDPackage: - PrintDebugString(" type == cGetAccessibleContextFromHWNDPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleContextFromHWNDPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) { GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType)); rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window); pkg->rAccessibleContext = (JOBJECT64)rAC; pkg->rVMID = HandleToLong(dialogWindow); - PrintDebugString(" -> returning AC = %p, vmID = %X", rAC, pkg->rVMID); + PrintDebugString("[INFO]: -> returning AC = %p, vmID = %X", rAC, pkg->rVMID); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)); } break; case cGetHWNDFromAccessibleContextPackage: - PrintDebugString(" type == cGetHWNDFromAccessibleContextPackage"); + PrintDebugString("[INFO]: type == cGetHWNDFromAccessibleContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) { GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType)); pkg->rHWND = ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) ); - PrintDebugString(" -> returning HWND = %p", pkg->rHWND); + PrintDebugString("[INFO]: -> returning HWND = %p", pkg->rHWND); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)); } break; @@ -558,15 +537,15 @@ /* ===== utility methods ===== */ case cSetTextContentsPackage: - PrintDebugString(" type == cSetTextContentsPackage"); + PrintDebugString("[INFO]: type == cSetTextContentsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) { SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text); - PrintDebugString(" -> returning result = %d", pkg->rResult); + PrintDebugString("[INFO]: -> returning result = %d", pkg->rResult); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage)); } break; @@ -577,75 +556,76 @@ (GetParentWithRolePackage *) (buffer + sizeof(PackageType)); rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role); pkg->rAccessibleContext = (JOBJECT64)rAC; - PrintDebugString(" type == cGetParentWithRolePackage"); - PrintDebugString(" pkg->vmID: %X", pkg->vmID); - PrintDebugString(" pkg->accessibleContext: %p", (jobject)pkg->accessibleContext); - PrintDebugString(" pkg->role: %ls", pkg->role); - PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + PrintDebugString("[INFO]: type == cGetParentWithRolePackage\n"\ + " pkg->vmID: %X"\ + " pkg->accessibleContext: %p"\ + " pkg->role: %ls"\ + " -> returning rAccessibleContext = %p"\ + , pkg->vmID, (jobject)pkg->accessibleContext, pkg->role, rAC); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage)); } break; case cGetTopLevelObjectPackage: - PrintDebugString(" type == cGetTopLevelObjectPackage"); + PrintDebugString("[INFO]: type == cGetTopLevelObjectPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) { GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType)); rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext); pkg->rAccessibleContext = (JOBJECT64)rAC; - PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + PrintDebugString("[INFO]: -> returning rAccessibleContext = %p", rAC); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)); } break; case cGetParentWithRoleElseRootPackage: - PrintDebugString(" type == cGetParentWithRoleElseRootPackage"); + PrintDebugString("[INFO]: type == cGetParentWithRoleElseRootPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) { GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType)); rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role); pkg->rAccessibleContext = (JOBJECT64)rAC; - PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + PrintDebugString("[INFO]: -> returning rAccessibleContext = %p", rAC); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)); } break; case cGetObjectDepthPackage: - PrintDebugString(" type == cGetObjectDepthPackage"); + PrintDebugString("[INFO]: type == cGetObjectDepthPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) { GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext); - PrintDebugString(" -> returning rResult = %d", pkg->rResult); + PrintDebugString("[INFO]: -> returning rResult = %d", pkg->rResult); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage)); } break; case cGetActiveDescendentPackage: - PrintDebugString(" type == cGetActiveDescendentPackage"); + PrintDebugString("[INFO]: type == cGetActiveDescendentPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) { GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType)); rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext); pkg->rAccessibleContext = (JOBJECT64)rAC; - PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + PrintDebugString("[INFO]: -> returning rAccessibleContext = %p", rAC); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage)); } break; case cGetAccessibleContextAtPackage: - PrintDebugString(" type == cGetAccessibleContextAtPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleContextAtPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) { GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType)); @@ -653,13 +633,13 @@ windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y, (jobject)pkg->AccessibleContext); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)); } break; case cGetAccessibleContextWithFocusPackage: - PrintDebugString(" type == cGetAccessibleContextWithFocusPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleContextWithFocusPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) { GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); @@ -667,46 +647,46 @@ windowsThreadEntryPoints->getAccessibleContextWithFocus(); pkg->rVMID = HandleToLong(dialogWindow); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)); } break; case cGetAccessibleContextInfoPackage: - PrintDebugString(" type == cGetAccessibleContextInfoPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleContextInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) { GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleContextInfo( (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)); } break; case cGetAccessibleChildFromContextPackage: - PrintDebugString(" type == cGetAccessibleChildFromContextPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleChildFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) { GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType)); pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext( (jobject)pkg->AccessibleContext, pkg->childIndex); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)); } break; case cGetAccessibleParentFromContextPackage: - PrintDebugString(" type == cGetAccessibleParentFromContextPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleParentFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) { GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType)); pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext( (jobject)pkg->AccessibleContext); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)); } break; @@ -714,106 +694,106 @@ // ------------ begin AccessibleTable packages ------------------ case cGetAccessibleTableInfoPackage: - PrintDebugString(" ##### type == cGetAccessibleTableInfoPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) { GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext, &(pkg->rTableInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)); } break; case cGetAccessibleTableCellInfoPackage: - PrintDebugString(" ##### type == cGetAccessibleTableCellInfoPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableCellInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) { GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row, pkg->column, &(pkg->rTableCellInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)); } break; case cGetAccessibleTableRowHeaderPackage: - PrintDebugString(" ##### type == cGetAccessibleTableRowHeaderPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableRowHeaderPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) { GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext, &(pkg->rTableInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)); } break; case cGetAccessibleTableColumnHeaderPackage: - PrintDebugString(" ##### type == cGetAccessibleTableColumnHeaderPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableColumnHeaderPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) { GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext, &(pkg->rTableInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)); } break; case cGetAccessibleTableRowDescriptionPackage: - PrintDebugString(" ##### type == cGetAccessibleTableRowDescriptionPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableRowDescriptionPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) { GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType)); pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription( (jobject)pkg->accessibleContext, pkg->row); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)); } break; case cGetAccessibleTableColumnDescriptionPackage: - PrintDebugString(" ##### type == cGetAccessibleTableColumnDescriptionPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableColumnDescriptionPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) { GetAccessibleTableColumnDescriptionPackage *pkg = (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType)); pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription( (jobject)pkg->accessibleContext, pkg->column); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)); } break; case cGetAccessibleTableColumnSelectionCountPackage: - PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionCountPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableColumnSelectionCountPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) { GetAccessibleTableColumnSelectionCountPackage *pkg = (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType)); pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount( (jobject)pkg->accessibleTable); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)); } break; case cGetAccessibleTableRowSelectionCountPackage: - PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionCountPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableRowSelectionCountPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) { GetAccessibleTableRowSelectionCountPackage *pkg = (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType)); @@ -821,114 +801,114 @@ pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount( (jobject)pkg->accessibleTable); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)); } break; case cIsAccessibleTableRowSelectedPackage: - PrintDebugString(" ##### type == cIsAccessibleTableRowSelectedPackage"); + PrintDebugString("[INFO]: ##### type == cIsAccessibleTableRowSelectedPackage"); if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) { IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected( (jobject)pkg->accessibleTable, pkg->row); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)); } break; case cIsAccessibleTableColumnSelectedPackage: - PrintDebugString(" ##### type == cIsAccessibleTableColumnSelectedPackage"); + PrintDebugString("[INFO]: ##### type == cIsAccessibleTableColumnSelectedPackage"); if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) { IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected( (jobject)pkg->accessibleTable, pkg->column); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)); } break; case cGetAccessibleTableColumnSelectionsPackage: - PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionsPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableColumnSelectionsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) { GetAccessibleTableColumnSelectionsPackage *pkg = (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType)); - PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count); + PrintDebugString("[INFO]: ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count); windowsThreadEntryPoints->getAccessibleTableColumnSelections( (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); for (int i = 0; i < pkg->count; i++) { - PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]); + PrintDebugString("[INFO]: ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]); } - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)); } break; case cGetAccessibleTableRowSelectionsPackage: - PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionsPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableRowSelectionsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) { GetAccessibleTableRowSelectionsPackage *pkg = (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTableRowSelections( (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)); } break; case cGetAccessibleTableRowPackage: - PrintDebugString(" ##### type == cGetAccessibleTableRowPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableRowPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) { GetAccessibleTableRowPackage *pkg = (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType)); pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow( (jobject)pkg->accessibleTable, pkg->index); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)); } break; case cGetAccessibleTableColumnPackage: - PrintDebugString(" ##### type == cGetAccessibleTableColumnPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableColumnPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) { GetAccessibleTableColumnPackage *pkg = (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType)); pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn( (jobject)pkg->accessibleTable, pkg->index); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)); } break; case cGetAccessibleTableIndexPackage: - PrintDebugString(" ##### type == cGetAccessibleTableIndexPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleTableIndexPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) { GetAccessibleTableIndexPackage *pkg = (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType)); pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex( (jobject)pkg->accessibleTable, pkg->row, pkg->column); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)); } break; @@ -939,15 +919,15 @@ // ------------ begin AccessibleRelationSet packages ------------------ case cGetAccessibleRelationSetPackage: - PrintDebugString(" ##### type == cGetAccessibleRelationSetPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleRelationSetPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) { GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleRelationSet( (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)); } break; @@ -957,85 +937,85 @@ // ------------ begin AccessibleHypertext packages ------------------ case cGetAccessibleHypertextPackage: - PrintDebugString(" ##### type == cGetAccessibleHypertextPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleHypertextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) { GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleHypertext( (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)); } break; case cActivateAccessibleHyperlinkPackage: - PrintDebugString(" ##### type == cActivateAccessibleHyperlinkPackage"); + PrintDebugString("[INFO]: ##### type == cActivateAccessibleHyperlinkPackage"); if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) { ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink( (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)); } break; case cGetAccessibleHyperlinkCountPackage: - PrintDebugString(" ##### type == cGetAccessibleHyperlinkCountPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleHyperlinkCountPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) { GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType)); pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount( (jobject)pkg->accessibleContext); - PrintDebugString(" ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount); + PrintDebugString("[INFO]: ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)); } break; case cGetAccessibleHypertextExtPackage: - PrintDebugString(" ##### type == cGetAccessibleHypertextExtPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleHypertextExtPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) { GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType)); pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt( (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)); } break; case cGetAccessibleHypertextLinkIndexPackage: - PrintDebugString(" ##### type == cGetAccessibleHypertextLinkIndexPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleHypertextLinkIndexPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) { GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType)); pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex( (jobject)pkg->hypertext, pkg->charIndex); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)); } break; case cGetAccessibleHyperlinkPackage: - PrintDebugString(" ##### type == cGetAccessibleHyperlinkPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleHyperlinkPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) { GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex, &(pkg->rAccessibleHyperlinkInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)); } break; @@ -1045,59 +1025,59 @@ // ------------ begin Accessible KeyBindings, Icons and Actions case cGetAccessibleKeyBindingsPackage: - PrintDebugString(" ##### type == cGetAccessibleKeyBindingsPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleKeyBindingsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) { GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleKeyBindings ( (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)); } break; case cGetAccessibleIconsPackage: - PrintDebugString(" ##### type == cGetAccessibleIconsPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleIconsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) { GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleIcons ( (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)); } break; case cGetAccessibleActionsPackage: - PrintDebugString(" ##### type == cGetAccessibleActionsPackage"); + PrintDebugString("[INFO]: ##### type == cGetAccessibleActionsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) { GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleActions ( (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)); } break; case cDoAccessibleActionsPackage: - PrintDebugString(" ##### type == cDoAccessibleActionsPackage"); + PrintDebugString("[INFO]: ##### type == cDoAccessibleActionsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) { DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo), &(pkg->failure)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)); } break; @@ -1105,50 +1085,50 @@ // ------------ begin addtional methods for Teton case cGetVirtualAccessibleNamePackage: - PrintDebugString(" ##### type == GetVirtualAccessibleNamePackage"); + PrintDebugString("[INFO]: ##### type == GetVirtualAccessibleNamePackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) { GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext, pkg->rName, pkg->len); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)); } break; case cRequestFocusPackage: - PrintDebugString(" ##### type == RequestFocusPackage"); + PrintDebugString("[INFO]: ##### type == RequestFocusPackage"); if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) { RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->requestFocus ( (jobject)pkg->accessibleContext); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage)); } break; case cSelectTextRangePackage: - PrintDebugString(" ##### type == SelectTextRangePackage"); + PrintDebugString("[INFO]: ##### type == SelectTextRangePackage"); if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) { SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->selectTextRange ( (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage)); } break; case cGetTextAttributesInRangePackage: - PrintDebugString(" ##### type == GetTextAttributesInRangePackage"); + PrintDebugString("[INFO]: ##### type == GetTextAttributesInRangePackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) { GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType)); @@ -1156,30 +1136,30 @@ (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex, (AccessibleTextAttributesInfo *)&(pkg->attributes), &(pkg->rLength)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)); } break; case cGetVisibleChildrenCountPackage: - PrintDebugString(" ##### type == GetVisibleChildrenCountPackage"); + PrintDebugString("[INFO]: ##### type == GetVisibleChildrenCountPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) { GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType)); pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)); } break; case cGetVisibleChildrenPackage: - PrintDebugString(" ##### type == GetVisibleChildrenPackage"); + PrintDebugString("[INFO]: ##### type == GetVisibleChildrenPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) { GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType)); @@ -1187,23 +1167,23 @@ pkg->startIndex, &(pkg->rVisibleChildrenInfo)); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)); } break; case cSetCaretPositionPackage: - PrintDebugString(" ##### type == SetCaretPositionPackage"); + PrintDebugString("[INFO]: ##### type == SetCaretPositionPackage"); if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) { SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->setCaretPosition ( (jobject)pkg->accessibleContext, pkg->position); - PrintDebugString(" ##### processing succeeded"); + PrintDebugString("[INFO]: ##### processing succeeded"); } else { - PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: ##### processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage)); } break; @@ -1215,105 +1195,105 @@ // ------------ Accessible Text packages ------------------ case cGetAccessibleTextInfoPackage: - PrintDebugString(" type == cGetAccessibleTextInfoPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) { GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext, &(pkg->rTextInfo), pkg->x, pkg->y); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); } break; case cGetAccessibleTextItemsPackage: - PrintDebugString(" type == cGetAccessibleTextItemsPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextItemsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) { GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext, &(pkg->rTextItemsInfo), pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); } break; case cGetAccessibleTextSelectionInfoPackage: - PrintDebugString(" type == cGetAccessibleTextSelectionInfoPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextSelectionInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) { GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextSelectionInfo( (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)); } break; case cGetAccessibleTextAttributeInfoPackage: - PrintDebugString(" type == cGetAccessibleTextAttributeInfoPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextAttributeInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) { GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextAttributes( (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)); } break; case cGetAccessibleTextRectInfoPackage: - PrintDebugString(" type == cGetAccessibleTextRectInfoPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextRectInfoPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) { GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext, &(pkg->rTextRectInfo), pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)); } break; case cGetCaretLocationPackage: - PrintDebugString(" type == cGetCaretLocationPackage"); + PrintDebugString("[INFO]: type == cGetCaretLocationPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) { GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext, &(pkg->rTextRectInfo), pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage)); } break; case cGetAccessibleTextLineBoundsPackage: - PrintDebugString(" type == cGetAccessibleTextLineBoundsPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextLineBoundsPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) { GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext, pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)); } break; case cGetAccessibleTextRangePackage: - PrintDebugString(" type == cGetAccessibleTextRangePackage"); + PrintDebugString("[INFO]: type == cGetAccessibleTextRangePackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) { GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext, pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t))); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)); } break; @@ -1322,40 +1302,40 @@ // ------------ Accessible Value packages ------------------ case cGetCurrentAccessibleValueFromContextPackage: - PrintDebugString(" type == cGetCurrentAccessibleValueFromContextPackage"); + PrintDebugString("[INFO]: type == cGetCurrentAccessibleValueFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) { GetCurrentAccessibleValueFromContextPackage *pkg = (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext, (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)); } break; case cGetMaximumAccessibleValueFromContextPackage: - PrintDebugString(" type == cGetMaximumAccessibleValueFromContextPackage"); + PrintDebugString("[INFO]: type == cGetMaximumAccessibleValueFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) { GetMaximumAccessibleValueFromContextPackage *pkg = (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext, (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)); } break; case cGetMinimumAccessibleValueFromContextPackage: - PrintDebugString(" type == cGetMinimumAccessibleValueFromContextPackage"); + PrintDebugString("[INFO]: type == cGetMinimumAccessibleValueFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) { GetMinimumAccessibleValueFromContextPackage *pkg = (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext, (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)); } break; @@ -1363,90 +1343,90 @@ // ------------ Accessible Selection packages ------------------ case cAddAccessibleSelectionFromContextPackage: - PrintDebugString(" type == cAddAccessibleSelectionFromContextPackage"); + PrintDebugString("[INFO]: type == cAddAccessibleSelectionFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) { AddAccessibleSelectionFromContextPackage *pkg = (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)); } break; case cClearAccessibleSelectionFromContextPackage: - PrintDebugString(" type == cClearAccessibleSelectionFromContextPackage"); + PrintDebugString("[INFO]: type == cClearAccessibleSelectionFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) { ClearAccessibleSelectionFromContextPackage *pkg = (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)); } break; case cGetAccessibleSelectionFromContextPackage: - PrintDebugString(" type == cGetAccessibleSelectionFromContextPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleSelectionFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) { GetAccessibleSelectionFromContextPackage *pkg = (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext( (jobject)pkg->AccessibleContext, pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)); } break; case cGetAccessibleSelectionCountFromContextPackage: - PrintDebugString(" type == cGetAccessibleSelectionCountFromContextPackage"); + PrintDebugString("[INFO]: type == cGetAccessibleSelectionCountFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) { GetAccessibleSelectionCountFromContextPackage *pkg = (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType)); pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext( (jobject)pkg->AccessibleContext); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)); } break; case cIsAccessibleChildSelectedFromContextPackage: - PrintDebugString(" type == cIsAccessibleChildSelectedFromContextPackage"); + PrintDebugString("[INFO]: type == cIsAccessibleChildSelectedFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) { IsAccessibleChildSelectedFromContextPackage *pkg = (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType)); pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext( (jobject)pkg->AccessibleContext, pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)); } break; case cRemoveAccessibleSelectionFromContextPackage: - PrintDebugString(" type == cRemoveAccessibleSelectionFromContextPackage"); + PrintDebugString("[INFO]: type == cRemoveAccessibleSelectionFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) { RemoveAccessibleSelectionFromContextPackage *pkg = (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, pkg->index); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)); } break; case cSelectAllAccessibleSelectionFromContextPackage: - PrintDebugString(" type == cSelectAllAccessibleSelectionFromContextPackage"); + PrintDebugString("[INFO]: type == cSelectAllAccessibleSelectionFromContextPackage"); if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) { SelectAllAccessibleSelectionFromContextPackage *pkg = (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)); } break; @@ -1455,60 +1435,60 @@ // ------------ event notification management packages ------------------ case cAddJavaEventNotificationPackage: - PrintDebugString(" type = cAddJavaEventNotificationPackage"); + PrintDebugString("[INFO]: type = cAddJavaEventNotificationPackage"); if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) { AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) ); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)); } break; case cRemoveJavaEventNotificationPackage: - PrintDebugString(" type = cRemoveJavaEventNotificationPackage"); + PrintDebugString("[INFO]: type = cRemoveJavaEventNotificationPackage"); if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) { RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow )); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)); } break; case cAddAccessibilityEventNotificationPackage: - PrintDebugString(" type = cAddAccessibilityEventNotificationPackage"); + PrintDebugString("[INFO]: type = cAddAccessibilityEventNotificationPackage"); if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) { AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)); } break; case cRemoveAccessibilityEventNotificationPackage: - PrintDebugString(" type = cRemoveAccessibilityEventNotificationPackage"); + PrintDebugString("[INFO]: type = cRemoveAccessibilityEventNotificationPackage"); if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) { RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)); } break; default: - PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + PrintDebugString("[ERROR]: processing FAILED!! -> don't know how to handle type = %X", *type); returnVal = -1; break; } - PrintDebugString(" package processing completed"); + PrintDebugString("[INFO]: package processing completed"); return returnVal; } @@ -1527,17 +1507,17 @@ */ LRESULT JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) { - PrintDebugString(" in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename); + PrintDebugString("[INFO]: in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename); AccessBridgeATInstance *newAT = new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs); - PrintDebugString(" just created a new ATInstance = %p, old = %p", newAT, ATs); + PrintDebugString("[INFO]: just created a new ATInstance = %p, old = %p", newAT, ATs); ATs = newAT; LRESULT returnVal = ATs->initiateIPC(); if (returnVal == 0) { - PrintDebugString(" Successfully initiated IPC with AT!!!"); + PrintDebugString("[INFO]: Successfully initiated IPC with AT!!!"); } else { - PrintDebugString(" ERROR: Failed to initiate IPC with AT!!!"); + PrintDebugString("[ERROR]: Failed to initiate IPC with AT!!!"); } return returnVal; @@ -1550,9 +1530,9 @@ */ void JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) { - PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow); + PrintDebugString("[INFO]: in JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow); if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! -> ATs == 0! (shouldn't happen here)"); + PrintDebugString("[ERROR]: -> ATs == 0! (shouldn't happen here)"); return; } @@ -1564,20 +1544,20 @@ removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow); removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow); delete currentAT; - PrintDebugString(" data structures successfully removed"); + PrintDebugString("[INFO]: data structures successfully removed"); } else { while (currentAT != (AccessBridgeATInstance *) NULL) { if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) { previousAT->nextATInstance = currentAT->nextATInstance; delete currentAT; - PrintDebugString(" data structures successfully removed"); + PrintDebugString("[INFO]: data structures successfully removed"); return; } else { previousAT = currentAT; currentAT = currentAT->nextATInstance; } } - PrintDebugString(" ERROR!! couldn't find matching data structures!"); + PrintDebugString("[ERROR]: couldn't find matching data structures!"); } } @@ -1595,13 +1575,13 @@ */ void JavaAccessBridge::releaseJavaObject(jobject object) { - PrintDebugString("In JavaAccessBridge::releaseJavaObject"); - PrintDebugString(" object X: %p", object); + PrintDebugString("[INFO]: In JavaAccessBridge::releaseJavaObject"); + PrintDebugString("[INFO]: object X: %p", object); if (windowsThreadJNIEnv != (JNIEnv *) 0) { windowsThreadJNIEnv->DeleteGlobalRef(object); - PrintDebugString(" global reference deleted.", object); + PrintDebugString("[INFO]: global reference deleted.", object); } else { - PrintDebugString(" Error! windowsThreadJNIEnv == 0"); + PrintDebugString("[ERROR]: windowsThreadJNIEnv == 0"); } } @@ -1615,23 +1595,23 @@ JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) { // walk through list of ATs, find this one and add this type // and, if we weren't listening for these before, ask Java for 'em - PrintDebugString(" adding Java event type %016I64X to HWND %p", type, DLLwindow); + PrintDebugString("[INFO]: adding Java event type %016I64X to HWND %p", type, DLLwindow); AccessBridgeATInstance *ati = ATs; long globalEventMask = 0; while (ati != (AccessBridgeATInstance *) 0) { if (ati->winAccessBridgeWindow == DLLwindow) { ati->javaEventMask |= type; - PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + PrintDebugString("[INFO]: found HWND, javaEventMask now is %X", ati->javaEventMask); } else { globalEventMask |= ati->javaEventMask; } ati = ati->nextATInstance; } - PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + PrintDebugString("[INFO]: union of all Java AT event masks: %X", globalEventMask); if (!(globalEventMask & type)) { // no other ATs wanted this event; // start getting them from Java - PrintDebugString(" no other AT wanted this Java event (so not registered); adding to AccessBridge.java"); + PrintDebugString("[INFO]: no other AT wanted this Java event (so not registered); adding to AccessBridge.java"); windowsThreadEntryPoints->addJavaEventNotification(type); } } @@ -1644,23 +1624,23 @@ JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) { // walk through list of ATs, find this one and remove this type // and, if no other AT wants 'em either, tell Java we no longer want 'em - PrintDebugString(" removing Java event type %016I64X from HWND %p", type, DLLwindow); + PrintDebugString("[INFO]: removing Java event type %016I64X from HWND %p", type, DLLwindow); AccessBridgeATInstance *ati = ATs; long globalEventMask = 0; while (ati != (AccessBridgeATInstance *) 0) { if (ati->winAccessBridgeWindow == DLLwindow) { ati->javaEventMask &= (0xFFFFFFFF - type); - PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + PrintDebugString("[INFO]: found HWND, javaEventMask now is %X", ati->javaEventMask); } else { globalEventMask |= ati->javaEventMask; } ati = ati->nextATInstance; } - PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + PrintDebugString("[INFO]: union of all Java AT event masks: %X", globalEventMask); if (!(globalEventMask & type)) { // no other ATs wanted this event; // stop getting them from Java - PrintDebugString(" no other AT wanted this Java event (so can remove); removing from AccessBridge.java"); + PrintDebugString("[INFO]: no other AT wanted this Java event (so can remove); removing from AccessBridge.java"); windowsThreadEntryPoints->removeJavaEventNotification(type); } } @@ -1674,23 +1654,23 @@ JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) { // walk through list of ATs, find this one and add this type // and, if we weren't listening for these before, ask Java for 'em - PrintDebugString(" adding Accesibility event type %016I64X to HWND %p", type, DLLwindow); + PrintDebugString("[INFO]: adding Accesibility event type %016I64X to HWND %p", type, DLLwindow); AccessBridgeATInstance *ati = ATs; long globalEventMask = 0; while (ati != (AccessBridgeATInstance *) 0) { if (ati->winAccessBridgeWindow == DLLwindow) { ati->accessibilityEventMask |= type; - PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + PrintDebugString("[INFO]: found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); } else { globalEventMask |= ati->accessibilityEventMask; } ati = ati->nextATInstance; } - PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + PrintDebugString("[INFO]: union of all Accessibility AT event masks: %X", globalEventMask); if (!(globalEventMask & type)) { // no other ATs wanted this event; // start getting them from Java - PrintDebugString(" no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java"); + PrintDebugString("[INFO]: no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java"); windowsThreadEntryPoints->addAccessibilityEventNotification(type); } } @@ -1703,23 +1683,23 @@ JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) { // walk through list of ATs, find this one and remove this type // and, if no other AT wants 'em either, tell Java we no longer want 'em - PrintDebugString(" removing Accesibility event type %016I64X from HWND %p", type, DLLwindow); + PrintDebugString("[INFO]: removing Accesibility event type %016I64X from HWND %p", type, DLLwindow); AccessBridgeATInstance *ati = ATs; long globalEventMask = 0; while (ati != (AccessBridgeATInstance *) 0) { if (ati->winAccessBridgeWindow == DLLwindow) { ati->accessibilityEventMask &= (0xFFFFFFFF - type); - PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + PrintDebugString("[INFO]: found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); } else { globalEventMask |= ati->accessibilityEventMask; } ati = ati->nextATInstance; } - PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + PrintDebugString("[INFO]: union of all Accessibility AT event masks: %X", globalEventMask); if (!(globalEventMask & type)) { // no other ATs wanted this event; // stop getting them from Java - PrintDebugString(" no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java"); + PrintDebugString("[INFO]: no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java"); windowsThreadEntryPoints->removeAccessibilityEventNotification(type); } } @@ -1736,13 +1716,13 @@ jobject event, jobject source, jint oldValue, jint newValue) { - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -1758,17 +1738,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif pkg->oldPosition = oldValue; @@ -1778,7 +1758,7 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyCaretChange event"); + PrintDebugString("[INFO]: done with propertyCaretChange event"); } /** @@ -1790,13 +1770,13 @@ jobject event, jobject source, jstring oldValue, jstring newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -1813,17 +1793,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif if (oldValue != (jstring) 0) { @@ -1864,7 +1844,7 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyDescriptionChange event"); + PrintDebugString("[INFO]: done with propertyDescriptionChange event"); } /** @@ -1876,13 +1856,13 @@ jobject event, jobject source, jstring oldValue, jstring newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -1899,17 +1879,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyNameChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif if (oldValue != (jstring) 0) { @@ -1950,7 +1930,7 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyNameChange event"); + PrintDebugString("[INFO]: done with propertyNameChange event"); } @@ -1962,12 +1942,12 @@ JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj, jobject event, jobject source) { - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)", env, callingObj, event, source); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -1983,24 +1963,24 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with propertySelectionChange event"); + PrintDebugString("[INFO]: done with propertySelectionChange event"); } @@ -2013,13 +1993,13 @@ jobject event, jobject source, jstring oldValue, jstring newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2036,17 +2016,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyStateChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif if (oldValue != (jstring) 0) { @@ -2087,7 +2067,7 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyStateChange event"); + PrintDebugString("[INFO]: done with propertyStateChange event"); } @@ -2099,12 +2079,12 @@ JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj, jobject event, jobject source) { - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)", env, callingObj, event, source); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2120,24 +2100,24 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyTextChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p",pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyTextChange event"); + PrintDebugString("[INFO]: done with propertyTextChange event"); } @@ -2150,13 +2130,13 @@ jobject event, jobject source, jstring oldValue, jstring newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2173,17 +2153,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyValueChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif if (oldValue != (jstring) 0) { @@ -2224,7 +2204,7 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyValueChange event"); + PrintDebugString("[INFO]: done with propertyValueChange event"); } /** @@ -2235,12 +2215,12 @@ JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, jobject event, jobject source) { - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)", env, callingObj, event, source); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2256,24 +2236,24 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyVisibleDataChange event"); + PrintDebugString("[INFO]: done with propertyVisibleDataChange event"); } @@ -2286,13 +2266,13 @@ jobject event, jobject source, jobject oldValue, jobject newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2308,7 +2288,7 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyChildChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); @@ -2316,22 +2296,24 @@ pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); - PrintDebugString(" GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext); - PrintDebugString(" GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p"\ + " GlobalRef'd OldChildAC: %p"\ + " GlobalRef'd NewChildAC: %p"\ + , pkg->Event, pkg->AccessibleContextSource, pkg->oldChildAccessibleContext, pkg->newChildAccessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); - PrintDebugString(" GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext); - PrintDebugString(" GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X"\ + " GlobalRef'd OldChildAC: %016I64X"\ + " GlobalRef'd NewChildAC: %016I64X"\ + , pkg->Event, pkg->AccessibleContextSource, pkg->oldChildAccessibleContext, pkg->newChildAccessibleContext); #endif ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyChildChange event"); + PrintDebugString("[INFO]: done with propertyChildChange event"); } @@ -2344,13 +2326,13 @@ jobject event, jobject source, jobject oldValue, jobject newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2366,7 +2348,7 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); @@ -2374,22 +2356,24 @@ pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); - PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext); - PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p"\ + " GlobalRef'd OldActiveDescendentAC: %p"\ + " GlobalRef'd NewActiveDescendentAC: %p"\ + , pkg->Event, pkg->AccessibleContextSource, pkg->oldActiveDescendentAccessibleContext, pkg->newActiveDescendentAccessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); - PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext); - PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X"\ + " GlobalRef'd OldActiveDescendentAC: %016I64X"\ + " GlobalRef'd NewActiveDescendentAC: %016I64X"\ + , pkg->Event, pkg->AccessibleContextSource, pkg->oldActiveDescendentAccessibleContext, pkg->newActiveDescendentAccessibleContext); #endif ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyActiveChange event"); + PrintDebugString("[INFO]: done with propertyActiveChange event"); } /** @@ -2401,13 +2385,13 @@ jobject event, jobject source, jstring oldValue, jstring newValue){ - PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)", + PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)", env, callingObj, event, source, oldValue, newValue); // sanity check if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; // panic! } @@ -2424,17 +2408,17 @@ while (ati != (AccessBridgeATInstance *) 0) { if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); // make new GlobalRefs for this AT pkg->Event = (JOBJECT64)env->NewGlobalRef(event); pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif if (oldValue != (jstring) 0) { @@ -2475,31 +2459,31 @@ } ati = ati->nextATInstance; } - PrintDebugString(" done with propertyTableModelChange event"); + PrintDebugString("[INFO]: done with propertyTableModelChange event"); } #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) #define PRINT_GLOBALREFS() \ - PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); \ - PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %p"\ + " GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource); #else // JOBJECT64 is jlong (64 bit) #define PRINT_GLOBALREFS() \ - PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); \ - PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString("[INFO]: GlobalRef'd Event: %016I64X"\ + " GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource); #endif #define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant) \ void JavaAccessBridge::function(JNIEnv *env, jobject callingObj, \ jobject eventObj, jobject source) { \ \ - PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X", \ - eventConstant, env, callingObj, eventObj, source, javaVM); \ + PrintDebugString("[INFO]: Firing event id = %d(%p, %p, %p, %p); vmID = %X", \ + eventConstant, env, callingObj, eventObj, source, dialogWindow);\ \ /* sanity check */ \ if (ATs == (AccessBridgeATInstance *) 0) { \ - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); \ + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); \ return; /* panic! */ \ } \ \ @@ -2513,11 +2497,11 @@ /* make new Global Refs, send events only to those ATs that want 'em */ \ AccessBridgeATInstance *ati = ATs; \ while (ati != (AccessBridgeATInstance *) 0) { \ - PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X", \ + PrintDebugString("[INFO]: javaEventMask = %X eventConstant=%d pkg->vmID=%X",\ ati->javaEventMask, eventConstant, pkg->vmID ); \ if (ati->javaEventMask & eventConstant) { \ \ - PrintDebugString(" sending to AT"); \ + PrintDebugString("[INFO]: sending to AT"); \ /* make new GlobalRefs for this AT */ \ pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj); \ pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); \ @@ -2527,17 +2511,17 @@ } \ ati = ati->nextATInstance; \ } \ - PrintDebugString(" done with firing AWT event"); \ + PrintDebugString("[INFO]: done with firing AWT event"); \ } void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) { - PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X", - cJavaShutdownEvent, env, callingObj, javaVM); + PrintDebugString("[INFO]: Firing event id = %d(%p, %p); vmID = %X", + cJavaShutdownEvent, env, callingObj, dialogWindow); /* sanity check */ if (ATs == (AccessBridgeATInstance *) 0) { - PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)"); return; /* panic! */ } @@ -2552,12 +2536,12 @@ AccessBridgeATInstance *ati = ATs; while (ati != (AccessBridgeATInstance *) 0) { if (ati->javaEventMask & cJavaShutdownEvent) { - PrintDebugString(" sending to AT"); + PrintDebugString("[INFO]: sending to AT"); ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent); } ati = ati->nextATInstance; } - PrintDebugString(" done with firing AWT event"); + PrintDebugString("[INFO]: done with firing AWT event"); } FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent) diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.h openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.h --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.h 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/JavaAccessBridge.h 2020-01-15 20:05:09.000000000 +0000 @@ -44,7 +44,7 @@ LPVOID lpvReserved); void AppendToCallOutput(char *s); BOOL APIENTRY AccessBridgeDialogProc(HWND hDlg, UINT message, - UINT wParam, LONG lParam); + WPARAM wParam, LPARAM lParam); } /** diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/WinAccessBridge.cpp openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/WinAccessBridge.cpp --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/bridge/WinAccessBridge.cpp 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/bridge/WinAccessBridge.cpp 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ // Remind user later that a new JVM was installed case cRemindThereIsNewJVM: - PrintDebugString(" newJVMDialogProc: cRemindThereIsNewJVM"); + PrintDebugString("[INFO]: newJVMDialogProc: cRemindThereIsNewJVM"); // do nothing EndDialog(hwndDlg, wParam); return TRUE; @@ -130,13 +130,14 @@ switch (fdwReason) { case DLL_PROCESS_ATTACH: // A Windows executable loaded us - PrintDebugString("DLL_PROCESS_ATTACH"); + initializeFileLogger("windows_access_bridge"); + PrintDebugString("[INFO]: DLL_PROCESS_ATTACH"); theWindowsAccessBridge = new WinAccessBridge(hinstDll); break; case DLL_PROCESS_DETACH: // A Windows executable unloaded us if (theWindowsAccessBridge != (WinAccessBridge *) 0) { - PrintDebugString("*** AccessBridgeDialogProc -> deleting theWindowsAccessBridge"); + PrintDebugString("[INFO]: *** AccessBridgeDialogProc -> deleting theWindowsAccessBridge"); delete theWindowsAccessBridge; } break; @@ -173,15 +174,15 @@ switch (message) { case WM_INITDIALOG: - PrintDebugString("AccessBridgeDialogProc -> Initializing"); + PrintDebugString("[INFO]: AccessBridgeDialogProc -> Initializing"); break; // call from Java with data for us to deliver case WM_COPYDATA: if (theDialogWindow == (HWND) wParam) { - PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL"); + PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL"); } else { - PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam); + PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam); sentToUs = (COPYDATASTRUCT *) lParam; package = (char *) sentToUs->lpData; theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData); @@ -190,7 +191,7 @@ // message to ourselves -> de-queue messages and send 'em case AB_MESSAGE_QUEUED: - PrintDebugString("AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves"); + PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves"); theWindowsAccessBridge->receiveAQueuedPackage(); break; @@ -214,12 +215,12 @@ // to the message queue. That would delay the destruction of the instance // until the chain is not being traversed. case AB_DLL_GOING_AWAY: - PrintDebugString("***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message"); + PrintDebugString("[INFO]: ***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message"); if (isVMInstanceChainInUse) { - PrintDebugString(" javaVMs chain in use, calling PostMessage"); + PrintDebugString("[INFO]: javaVMs chain in use, calling PostMessage"); PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0); } else { - PrintDebugString(" calling javaVMDestroyed"); + PrintDebugString("[INFO]: calling javaVMDestroyed"); theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam); } break; @@ -228,7 +229,7 @@ // the JavaVM is saying "hi"! // wParam == sourceHwnd; lParam == JavaVMID if (message == theFromJavaHelloMsgID) { - PrintDebugString("AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam); + PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam); theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam); } break; @@ -250,7 +251,7 @@ */ WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) { - PrintDebugString("WinAccessBridge ctor"); + PrintDebugString("[INFO]: WinAccessBridge ctor"); // IntializeCriticalSection should only be called once. InitializeCriticalSection(&sendMemoryIPCLock); @@ -276,25 +277,25 @@ // -> shut down all event listening // -> release all objects held in the JVM by us - PrintDebugString("*****in WinAccessBridge::~WinAccessBridge()"); + PrintDebugString("[INFO]: *****in WinAccessBridge::~WinAccessBridge()"); // send a broadcast msg.; let other AccessBridge DLLs know we're going away AccessBridgeJavaVMInstance *current = javaVMs; while (current != (AccessBridgeJavaVMInstance *) 0) { - PrintDebugString(" telling %p we're going away", current->javaAccessBridgeWindow); + PrintDebugString("[INFO]: telling %p we're going away", current->javaAccessBridgeWindow); SendMessage(current->javaAccessBridgeWindow, AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); current = current->nextJVMInstance; } - PrintDebugString(" finished telling JVMs about our demise"); + PrintDebugString("[INFO]: finished telling JVMs about our demise"); delete eventHandler; delete messageQueue; delete javaVMs; - PrintDebugString(" finished deleting eventHandler, messageQueue, and javaVMs"); - PrintDebugString("GOODBYE CRUEL WORLD..."); + PrintDebugString("[INFO]: finished deleting eventHandler, messageQueue, and javaVMs"); + PrintDebugString("[INFO]: GOODBYE CRUEL WORLD..."); DestroyWindow(theDialogWindow); } @@ -338,7 +339,7 @@ WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) { LRESULT returnVal; - PrintDebugString("in JavaAccessBridge::rendezvousWithNewJavaDLL(%p, %X)", + PrintDebugString("[INFO]: in WinAccessBridge::rendezvousWithNewJavaDLL(%p, %X)", JavaBridgeDLLwindow, vmID); isVMInstanceChainInUse = true; @@ -354,23 +355,23 @@ long javaEventMask = eventHandler->getJavaEventMask(); long accessibilityEventMask = eventHandler->getAccessibilityEventMask(); - PrintDebugString(" Setting Java event mask to: %X", javaEventMask); + PrintDebugString("[INFO]: Setting Java event mask to: %X", javaEventMask); if (javaEventMask != 0) { addJavaEventNotification(javaEventMask); } - PrintDebugString(" Setting Accessibility event mask to: %X", accessibilityEventMask); + PrintDebugString("[INFO]: Setting Accessibility event mask to: %X", accessibilityEventMask); if (accessibilityEventMask != 0) { addAccessibilityEventNotification(accessibilityEventMask); } } else { - PrintDebugString(" ERROR: Failed to initiate IPC with newly created JavaVM!!!"); + PrintDebugString("[ERROR]: Failed to initiate IPC with newly created JavaVM!!!"); return FALSE; } - PrintDebugString(" Success!! We rendezvoused with the JavaDLL"); + PrintDebugString("[INFO]: Success!! We rendezvoused with the JavaDLL"); return returnVal; } @@ -421,7 +422,7 @@ return FALSE; } } else { - PrintDebugString("ERROR sending memory package: couldn't find destWindow"); + PrintDebugString("[ERROR]: sending memory package: couldn't find destWindow"); return FALSE; } return TRUE; @@ -434,7 +435,7 @@ */ BOOL WinAccessBridge::queuePackage(char *buffer, long bufsize) { - PrintDebugString(" in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize); + PrintDebugString("[INFO]: in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize); AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize); @@ -454,37 +455,37 @@ WinAccessBridge::receiveAQueuedPackage() { AccessBridgeQueueElement *element = NULL; - PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()"); + PrintDebugString("[INFO]: in WinAccessBridge::receiveAQueuedPackage()"); // ensure against re-entrancy problems... if (messageQueue->getRemoveLockSetting() == FALSE) { messageQueue->setRemoveLock(TRUE); - PrintDebugString(" dequeueing message"); + PrintDebugString("[INFO]: dequeueing message"); QueueReturns result = messageQueue->remove(&element); switch (result) { case cQueueBroken: - PrintDebugString(" ERROR!!! Queue seems to be broken!"); + PrintDebugString("[ERROR]: Queue seems to be broken!"); messageQueue->setRemoveLock(FALSE); return FALSE; case cMoreMessages: case cQueueEmpty: if (element != (AccessBridgeQueueElement *) 0) { - PrintDebugString(" found one; sending it!"); + PrintDebugString("[INFO]: found one; sending it!"); processPackage(element->buffer, element->bufsize); delete element; } else { - PrintDebugString(" ODD... element == 0!"); + PrintDebugString("[WARN]: ODD... element == 0!"); return FALSE; } break; case cQueueInUse: - PrintDebugString(" Queue in use, will try again later..."); + PrintDebugString("[WARN]: Queue in use, will try again later..."); PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); break; @@ -493,7 +494,7 @@ return FALSE; // should never get something we don't recognize! } } else { - PrintDebugString(" unable to dequeue message; remove lock is set"); + PrintDebugString("[WARN]: unable to dequeue message; remove lock is set"); PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891 } @@ -510,13 +511,13 @@ */ void WinAccessBridge::preProcessPackage(char *buffer, long bufsize) { - PrintDebugString("PreProcessing package sent from Java:"); + PrintDebugString("[INFO]: PreProcessing package sent from Java:"); PackageType *type = (PackageType *) buffer; switch (*type) { - PrintDebugString(" type == %X", *type); + PrintDebugString("[INFO]: type == %X", *type); // event packages all get queued for later handling //case cPropertyChangePackage: @@ -555,11 +556,11 @@ // perhaps there will be some other packages to process at some point... // default: - PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + PrintDebugString("[ERROR]: processing FAILED!! -> don't know how to handle type = %X", *type); break; } - PrintDebugString(" package preprocessing completed"); + PrintDebugString("[INFO]: package preprocessing completed"); } @@ -568,12 +569,12 @@ if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ eventPackage *pkg = \ (eventPackage *) (buffer + sizeof(PackageType)); \ - PrintDebugString(" begin callback to AT, type == %X", *type); \ + PrintDebugString("[INFO]: begin callback to AT, type == %X", *type); \ theWindowsAccessBridge->eventHandler->fireEventMethod( \ pkg->vmID, pkg->Event, pkg->AccessibleContextSource); \ - PrintDebugString(" event callback complete!"); \ + PrintDebugString("[INFO]: event callback complete!"); \ } else { \ - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", \ bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ } \ break; @@ -583,13 +584,13 @@ if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ eventPackage *pkg = \ (eventPackage *) (buffer + sizeof(PackageType)); \ - PrintDebugString(" begin callback to AT, type == %X", *type); \ + PrintDebugString("[INFO]: begin callback to AT, type == %X", *type); \ theWindowsAccessBridge->eventHandler->fireEventMethod( \ pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ pkg->oldValue, pkg->newValue); \ - PrintDebugString(" event callback complete!"); \ + PrintDebugString("[INFO]: event callback complete!"); \ } else { \ - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", \ bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ } \ break; @@ -599,13 +600,13 @@ if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ eventPackage *pkg = \ (eventPackage *) (buffer + sizeof(PackageType)); \ - PrintDebugString(" begin callback to AT, type == %X", *type); \ + PrintDebugString("[INFO]: begin callback to AT, type == %X", *type); \ theWindowsAccessBridge->eventHandler->fireEventMethod( \ pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ pkg->oldValue, pkg->newValue); \ - PrintDebugString(" event callback complete!"); \ + PrintDebugString("[INFO]: event callback complete!"); \ } else { \ - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", \ bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ } \ break; @@ -617,24 +618,24 @@ */ void WinAccessBridge::processPackage(char *buffer, long bufsize) { - PrintDebugString("WinAccessBridge::Processing package sent from Java:"); + PrintDebugString("[INFO]: WinAccessBridge::Processing package sent from Java:"); PackageType *type = (PackageType *) buffer; switch (*type) { - PrintDebugString(" type == %X", *type); + PrintDebugString("[INFO]: type == %X", *type); case cJavaShutdownPackage: - PrintDebugString(" type == cJavaShutdownPackage"); + PrintDebugString("[INFO]: type == cJavaShutdownPackage"); if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) { JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType)); theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID); - PrintDebugString(" event callback complete!"); - PrintDebugString(" event fired!"); + PrintDebugString("[INFO]: event callback complete!"); + PrintDebugString("[INFO]: event fired!"); } else { - PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + PrintDebugString("[ERROR]: processing FAILED!! -> bufsize = %d; expectation = %d", bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage)); } break; @@ -698,11 +699,11 @@ default: - PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + PrintDebugString("[ERROR]: processing FAILED!! -> don't know how to handle type = %X", *type); break; } - PrintDebugString(" package processing completed"); + PrintDebugString("[INFO]: package processing completed"); } @@ -710,7 +711,7 @@ void WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) { - PrintDebugString("***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow); + PrintDebugString("[INFO]: ***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; @@ -723,7 +724,7 @@ javaVMs = javaVMs->nextJVMInstance; delete currentVM; - PrintDebugString(" data structures successfully removed"); + PrintDebugString("[INFO]: data structures successfully removed"); // [[[FIXME]]] inform Windows AT that a JVM went away, // and that any jobjects it's got lying around for that JVM @@ -735,7 +736,7 @@ previousVM->nextJVMInstance = currentVM->nextJVMInstance; delete currentVM; - PrintDebugString(" data structures successfully removed"); + PrintDebugString("[INFO]: data structures successfully removed"); // [[[FIXME]]] inform Windows AT that a JVM went away, // and that any jobjects it's got lying around for that JVM @@ -747,7 +748,7 @@ currentVM = currentVM->nextJVMInstance; } } - PrintDebugString(" ERROR!! couldn't find matching data structures!"); + PrintDebugString("[ERROR]: couldn't find matching data structures!"); } isVMInstanceChainInUse = false; } @@ -765,9 +766,9 @@ void WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object); + PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object); + PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; @@ -802,15 +803,16 @@ *type = cGetAccessBridgeVersionPackage; pkg->vmID = vmID; - PrintDebugString("WinAccessBridge::getVersionInfo(%X, )", vmID); + PrintDebugString("[INFO]: WinAccessBridge::getVersionInfo(%X, )", vmID); HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo)); - PrintDebugString(" VMversion: %ls", info->VMversion); - PrintDebugString(" bridgeJavaClassVersion: %ls", info->bridgeJavaClassVersion); - PrintDebugString(" bridgeJavaDLLVersion: %ls", info->bridgeJavaDLLVersion); - PrintDebugString(" bridgeWinDLLVersion: %ls", info->bridgeWinDLLVersion); + PrintDebugString("[INFO]: VMversion: %ls\n"\ + " bridgeJavaClassVersion: %ls\n"\ + " bridgeJavaDLLVersion: %ls\n"\ + " bridgeWinDLLVersion: %ls\n"\ + , info->VMversion, info->bridgeJavaClassVersion, info->bridgeJavaDLLVersion, info->bridgeWinDLLVersion); return TRUE; } } @@ -843,7 +845,7 @@ return FALSE; } - PrintDebugString(" in WinAccessBridge::isJavaWindow"); + PrintDebugString("[INFO]: In WinAccessBridge::isJavaWindow"); @@ -853,7 +855,7 @@ *type = cIsJavaWindowPackage; pkg->window = (jint) window; - PrintDebugString("WinAccessBridge::isJavaWindow(%p)", window); + PrintDebugString("[INFO]: WinAccessBridge::isJavaWindow(%p)", window); isVMInstanceChainInUse = true; AccessBridgeJavaVMInstance *current = javaVMs; @@ -908,9 +910,9 @@ WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::isSameObject(%p %p)", obj1, obj2); + PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%p %p)", obj1, obj2); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2); + PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -928,14 +930,14 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { if (pkg->rResult != 0) { - PrintDebugString(" WinAccessBridge::isSameObject returning TRUE (same object)"); + PrintDebugString("[INFO]: WinAccessBridge::isSameObject returning TRUE (same object)"); return TRUE; } else { - PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (different object)"); + PrintDebugString("[INFO]: WinAccessBridge::isSameObject returning FALSE (different object)"); return FALSE; } } - PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)"); + PrintDebugString("[ERROR]: WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)"); return FALSE; } @@ -958,7 +960,7 @@ *type = cGetAccessibleContextFromHWNDPackage; pkg->window = (jint) window; - PrintDebugString("WinAccessBridge::getAccessibleContextFromHWND(%p, )", window); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextFromHWND(%p, )", window); DEBUG_CODE(pkg->rVMID = (long ) 0x01010101); DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101); @@ -971,15 +973,14 @@ if (pkg->rAccessibleContext != 0) { *vmID = pkg->rVMID; *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext; - PrintDebugString(" current->vmID = %X", current->vmID); - PrintDebugString(" pkg->rVMID = %X", pkg->rVMID); + PrintDebugString("[INFO]: current->vmID = %X, pkg->rVMID = %X", current->vmID, pkg->rVMID); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" pkg->rAccessibleContext = %p", pkg->rAccessibleContext); + PrintDebugString("[INFO]: pkg->rAccessibleContext = %p", pkg->rAccessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext); + PrintDebugString("[INFO]: pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext); #endif if (pkg->rVMID != current->vmID) { - PrintDebugString(" ERROR! getAccessibleContextFromHWND vmIDs don't match!"); + PrintDebugString("[ERROR]: getAccessibleContextFromHWND vmIDs don't match!"); isVMInstanceChainInUse = false; return FALSE; } @@ -994,7 +995,7 @@ // This isn't really an error; it just means that the HWND was for a non-Java // window. It's also possible the HWND was for a Java window but the JVM has // since been shut down and sendMemoryPackage returned FALSE. - PrintDebugString(" ERROR! getAccessibleContextFromHWND no matching HWND found!"); + PrintDebugString("[ERROR]: getAccessibleContextFromHWND no matching HWND found!"); return FALSE; } @@ -1003,7 +1004,7 @@ */ HWND WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) { - PrintDebugString(" in WinAccessBridge::getHWNDFromAccessibleContext"); + PrintDebugString("[INFO]: in WinAccessBridge::getHWNDFromAccessibleContext"); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return (HWND)0; } @@ -1015,9 +1016,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext); #endif HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -1081,7 +1082,7 @@ pkg->x = x; pkg->y = y; - PrintDebugString("WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y); HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { *AccessibleContext = pkg->rAccessibleContext; @@ -1114,7 +1115,7 @@ GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); *type = cGetAccessibleContextWithFocusPackage; - PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); // find vmID, etc. from HWND; ask that VM for the AC w/Focus HWND pkgVMID; if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) { @@ -1151,21 +1152,22 @@ pkg->AccessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo)); - PrintDebugString(" name: %ls", info->name); - PrintDebugString(" description: %ls", info->description); - PrintDebugString(" role: %ls", info->role); - PrintDebugString(" role_en_US: %ls", info->role_en_US); - PrintDebugString(" states: %ls", info->states); - PrintDebugString(" states_en_US: %ls", info->states_en_US); + PrintDebugString("[INFO]: name: %ls\n"\ + " description: %ls\n"\ + " role: %ls\n"\ + " role_en_US: %ls\n"\ + " states: %ls\n"\ + " states_en_US: %ls\n"\ + , info->name, info->description, info->role, info->role_en_US, info->states, info->states_en_US); return TRUE; } } @@ -1200,9 +1202,9 @@ pkg->childIndex = childIndex; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -1235,7 +1237,7 @@ pkg->vmID = vmID; pkg->AccessibleContext = AccessibleContext; - PrintDebugString("WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext); // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { @@ -1255,10 +1257,10 @@ AccessibleTableInfo *tableInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext, tableInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext, tableInfo); #endif @@ -1278,12 +1280,12 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); if (pkg->rTableInfo.rowCount != -1) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo succeeded"); return TRUE; } } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableInfo failed"); return FALSE; } @@ -1292,7 +1294,7 @@ jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { - PrintDebugString("##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID, accessibleTable, row, column, tableCellInfo); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1311,13 +1313,13 @@ if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext); + PrintDebugString("[INFO]: XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext); memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo)); - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableCellInfo succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableCellInfo failed"); return FALSE; } @@ -1326,9 +1328,9 @@ WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1345,12 +1347,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader succeeded"); memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableRowHeader failed"); return FALSE; } @@ -1358,9 +1360,9 @@ WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1377,12 +1379,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded"); memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnHeader failed"); return FALSE; } @@ -1392,10 +1394,10 @@ jint row) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext, row); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext, row); #endif @@ -1414,11 +1416,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription succeeded"); return pkg->rAccessibleContext; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableRowDescription failed"); return (JOBJECT64)0; } @@ -1428,10 +1430,10 @@ jint column) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext, column); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext, column); #endif @@ -1451,11 +1453,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded"); return pkg->rAccessibleContext; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnDescription failed"); return (JOBJECT64)0; } @@ -1463,9 +1465,9 @@ WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1483,11 +1485,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded"); return pkg->rCount; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed"); return 0; } @@ -1495,9 +1497,9 @@ WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1515,11 +1517,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected succeeded"); return pkg->rResult; } } - PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::isAccessibleTableRowSelected failed"); return FALSE; } @@ -1527,9 +1529,9 @@ WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1548,12 +1550,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections succeeded"); memcpy(selections, pkg->rSelections, count * sizeof(jint)); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableRowSelections failed"); return FALSE; } @@ -1562,10 +1564,10 @@ WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID, accessibleTable); #endif @@ -1584,20 +1586,20 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded"); return pkg->rCount; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed"); return 0; } BOOL WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1615,11 +1617,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded"); return pkg->rResult; } } - PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::isAccessibleTableColumnSelected failed"); return FALSE; } @@ -1628,9 +1630,9 @@ jint *selections) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable); #endif if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { @@ -1649,12 +1651,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded"); memcpy(selections, pkg->rSelections, count * sizeof(jint)); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelections failed"); return FALSE; } @@ -1662,10 +1664,10 @@ WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID, accessibleTable, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID, accessibleTable, index); #endif @@ -1685,11 +1687,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow succeeded"); return pkg->rRow; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableRow failed"); return 0; } @@ -1697,10 +1699,10 @@ WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID, accessibleTable, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID, accessibleTable, index); #endif @@ -1720,11 +1722,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn succeeded"); return pkg->rColumn; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumn failed"); return 0; } @@ -1732,10 +1734,10 @@ WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID, accessibleTable, row, column); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID, accessibleTable, row, column); #endif @@ -1756,11 +1758,11 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex succeeded"); return pkg->rIndex; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableIndex failed"); return 0; } @@ -1771,10 +1773,10 @@ AccessibleRelationSetInfo *relationSetInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID, accessibleContext, relationSetInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID, accessibleContext, relationSetInfo); #endif @@ -1792,14 +1794,14 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### pkg->rAccessibleRelationSetInfo.relationCount = %X", + PrintDebugString("[INFO]: ##### pkg->rAccessibleRelationSetInfo.relationCount = %X", pkg->rAccessibleRelationSetInfo.relationCount); memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo)); - PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleRelationSet failed"); return FALSE; } @@ -1811,10 +1813,10 @@ AccessibleHypertextInfo *hypertextInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID, accessibleContext, hypertextInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID, accessibleContext, hypertextInfo); #endif @@ -1834,13 +1836,13 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); - PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + PrintDebugString("[INFO]: ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleHypertext failed"); return FALSE; } @@ -1850,10 +1852,10 @@ JOBJECT64 accessibleHyperlink) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext, accessibleHyperlink); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext, accessibleHyperlink); #endif @@ -1873,7 +1875,7 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { return pkg->rResult; } - PrintDebugString(" WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)"); + PrintDebugString("[ERROR]: WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)"); return FALSE; } @@ -1887,10 +1889,10 @@ const AccessibleContext accessibleContext) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)", + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)", + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)", vmID, accessibleContext); #endif @@ -1908,12 +1910,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### hypetext link count = %d", pkg->rLinkCount); - PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded"); + PrintDebugString("[INFO]: ##### hypetext link count = %d", pkg->rLinkCount); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded"); return pkg->rLinkCount; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleHyperlinkCount failed"); return -1; } @@ -1931,10 +1933,10 @@ /* OUT */ AccessibleHypertextInfo *hypertextInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID, accessibleContext, hypertextInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID, accessibleContext, hypertextInfo); #endif @@ -1953,19 +1955,18 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### pkg->rSuccess = %d", pkg->rSuccess); + PrintDebugString("[INFO]: ##### pkg->rSuccess = %d", pkg->rSuccess); memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); if (pkg->rSuccess == TRUE) { - PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); - PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString("[INFO]: ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); } else { - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleHypertextExt failed"); } - return pkg->rSuccess;; + return pkg->rSuccess; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleHypertextExt failed"); return FALSE; } @@ -1982,10 +1983,10 @@ const jint charIndex) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)", + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)", vmID, hypertext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)", + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)", vmID, hypertext); #endif @@ -2004,12 +2005,12 @@ HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" ##### hypetext link index = %d", pkg->rLinkIndex); - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex succeeded"); + PrintDebugString("[INFO]: ##### hypetext link index = %d", pkg->rLinkIndex); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex succeeded"); return pkg->rLinkIndex; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex failed"); + PrintDebugString("[ERROR] ##### WinAccessBridge::getAccessibleHypertextLinkIndex failed"); return -1; } @@ -2025,10 +2026,10 @@ /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID, hypertext, hyperlinkInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID, hypertext, hyperlinkInfo); #endif @@ -2049,11 +2050,11 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo), sizeof(AccessibleHyperlinkInfo)); - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleHypertext failed"); return FALSE; } @@ -2065,10 +2066,10 @@ AccessibleKeyBindings *keyBindings) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID, accessibleContext, keyBindings); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID, accessibleContext, keyBindings); #endif @@ -2088,19 +2089,20 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings)); - PrintDebugString(" ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount); + PrintDebugString("[INFO]: ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount); for (int i = 0; i < keyBindings->keyBindingsCount; ++i) { - PrintDebugString(" Key Binding # %d", i+1); - PrintDebugString(" Modifiers: 0x%x", keyBindings->keyBindingInfo[i].modifiers); - PrintDebugString(" Character (hex): 0x%x", keyBindings->keyBindingInfo[i].character); - PrintDebugString(" Character (wide char): %lc", keyBindings->keyBindingInfo[i].character); + PrintDebugString("[INFO]: Key Binding # %d"\ + " Modifiers: 0x%x"\ + " Character (hex): 0x%x"\ + " Character (wide char): %lc"\ + , i+1, keyBindings->keyBindingInfo[i].modifiers, keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character); } - PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings succeeded"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings failed"); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings failed"); return FALSE; } @@ -2108,10 +2110,10 @@ WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID, accessibleContext, icons); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID, accessibleContext, icons); #endif @@ -2131,13 +2133,13 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons)); - PrintDebugString(" ##### icons.iconsCount = %d", icons->iconsCount); - PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons succeeded"); + PrintDebugString("[INFO]: ##### icons.iconsCount = %d", icons->iconsCount); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleIcons failed"); return FALSE; } @@ -2145,10 +2147,10 @@ WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID, accessibleContext, actions); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID, + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID, accessibleContext, actions); #endif @@ -2168,13 +2170,13 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions)); - PrintDebugString(" ##### actions.actionsCount = %d", actions->actionsCount); - PrintDebugString(" ##### WinAccessBridge::getAccessibleActions succeeded"); + PrintDebugString("[INFO]: ##### actions.actionsCount = %d", actions->actionsCount); + PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions succeeded"); return TRUE; } } - PrintDebugString(" ##### WinAccessBridge::getAccessibleActions failed"); + PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleActions failed"); return FALSE; } @@ -2183,11 +2185,11 @@ AccessibleActionsToDo *actionsToDo, jint *failure) { #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext, actionsToDo->actionsCount, actionsToDo->actions[0].name); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext, actionsToDo->actionsCount, actionsToDo->actions[0].name); #endif @@ -2209,7 +2211,7 @@ *failure = pkg->failure; return pkg->rResult; } - PrintDebugString(" WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)"); + PrintDebugString("[ERROR]: WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)"); return FALSE; } @@ -2234,9 +2236,9 @@ wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text); + PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text); + PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2271,18 +2273,19 @@ memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext); #endif - PrintDebugString(" pkg->vmID: %X", pkg->vmID); - PrintDebugString(" pkg->accessibleContext: %p", pkg->accessibleContext); - PrintDebugString(" pkg->role: %ls", pkg->role); + PrintDebugString("[INFO]: pkg->vmID: %X"\ + " pkg->accessibleContext: %p"\ + " pkg->role: %ls"\ + , pkg->vmID, pkg->accessibleContext, pkg->role); // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { - PrintDebugString(" pkg->rAccessibleContext: %p", pkg->rAccessibleContext); + PrintDebugString("[INFO]: pkg->rAccessibleContext: %p", pkg->rAccessibleContext); return pkg->rAccessibleContext; } } @@ -2310,9 +2313,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2345,9 +2348,9 @@ memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2378,9 +2381,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2410,9 +2413,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2451,16 +2454,16 @@ pkg->len = (int)max; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); if (destABWindow != (HWND) 0) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { wcsncpy(name, pkg->rName, max); - PrintDebugString(" WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name); + PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name); return TRUE; } } @@ -2486,9 +2489,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2521,10 +2524,10 @@ pkg->endIndex = endIndex; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext, startIndex, endIndex); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext, startIndex, endIndex); #endif // need to call only the HWND/VM that contains this AC @@ -2563,10 +2566,10 @@ #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext, startIndex, endIndex); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext, + PrintDebugString("[INFO]: WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext, startIndex, endIndex); #endif // need to call only the HWND/VM that contains this AC @@ -2600,9 +2603,9 @@ pkg->accessibleContext = accessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2635,9 +2638,9 @@ pkg->startIndex = startIndex; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2670,9 +2673,9 @@ pkg->position = position; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext); + PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2712,9 +2715,9 @@ pkg->y = y; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2722,9 +2725,10 @@ if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo)); if (pkg->rTextInfo.charCount != -1) { - PrintDebugString(" charCount: %d", textInfo->charCount); - PrintDebugString(" caretIndex: %d", textInfo->caretIndex); - PrintDebugString(" indexAtPoint: %d", textInfo->indexAtPoint); + PrintDebugString("[INFO]: charCount: %d"\ + " caretIndex: %d"\ + " indexAtPoint: %d"\ + , textInfo->charCount, textInfo->caretIndex, textInfo->indexAtPoint); return TRUE; } } @@ -2760,9 +2764,9 @@ pkg->rTextItemsInfo.sentence[0] = '\0'; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2799,9 +2803,9 @@ pkg->AccessibleContext = AccessibleContext; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2839,9 +2843,9 @@ pkg->index = index; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2877,9 +2881,9 @@ pkg->index = index; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2917,9 +2921,9 @@ pkg->index = index; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); + PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); + PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -2969,9 +2973,9 @@ pkg->index = index; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -3011,9 +3015,9 @@ pkg->end = end; #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) - PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end); #else // JOBJECT64 is jlong (64 bit) - PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end); + PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end); #endif // need to call only the HWND/VM that contains this AC HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); @@ -3290,7 +3294,7 @@ */ void WinAccessBridge::addJavaEventNotification(jlong type) { - PrintDebugString("WinAccessBridge::addJavaEventNotification(%016I64X)", type); + PrintDebugString("[INFO]: WinAccessBridge::addJavaEventNotification(%016I64X)", type); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; } @@ -3302,7 +3306,7 @@ pkg->type = type; pkg->DLLwindow = ABHandleToLong(dialogWindow); - PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + PrintDebugString("[INFO]: ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", *pkgType, pkg->type, pkg->DLLwindow); // send addEventNotification message to all JVMs @@ -3327,7 +3331,7 @@ */ void WinAccessBridge::removeJavaEventNotification(jlong type) { - PrintDebugString("in WinAccessBridge::removeJavaEventNotification(%016I64X)", type); + PrintDebugString("[INFO]: in WinAccessBridge::removeJavaEventNotification(%016I64X)", type); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; } @@ -3338,7 +3342,7 @@ pkg->type = type; pkg->DLLwindow = ABHandleToLong(dialogWindow); - PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + PrintDebugString("[INFO]: ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", *pkgType, pkg->type, pkg->DLLwindow); // send removeEventNotification message to all JVMs @@ -3365,7 +3369,7 @@ */ void WinAccessBridge::addAccessibilityEventNotification(jlong type) { - PrintDebugString("in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type); + PrintDebugString("[INFO]: in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; } @@ -3376,7 +3380,7 @@ pkg->type = type; pkg->DLLwindow = ABHandleToLong(dialogWindow); - PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + PrintDebugString("[INFO]: ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", *pkgType, pkg->type, pkg->DLLwindow); // send addEventNotification message to all JVMs @@ -3401,7 +3405,7 @@ */ void WinAccessBridge::removeAccessibilityEventNotification(jlong type) { - PrintDebugString("in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type); + PrintDebugString("[INFO]: in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type); if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { return; } @@ -3412,7 +3416,7 @@ pkg->type = type; pkg->DLLwindow = ABHandleToLong(dialogWindow); - PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + PrintDebugString("[INFO]: ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", *pkgType, pkg->type, pkg->DLLwindow); // send removeEventNotification message to all JVMs diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * 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,29 @@ JNIEXPORT void JNICALL Java_sun_java2d_opengl_WGLSurfaceData_initOps(JNIEnv *env, jobject wglsd, - jlong pConfigInfo, + jobject gc, jlong pConfigInfo, jobject peer, jlong hwnd) { - OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, wglsd, + OGLSDOps *oglsdo; + WGLSDOps *wglsdo; + + gc = (*env)->NewGlobalRef(env, gc); + if (gc == NULL) { + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + return; + } + + oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, wglsd, sizeof(OGLSDOps)); - WGLSDOps *wglsdo = (WGLSDOps *)malloc(sizeof(WGLSDOps)); + if (oglsdo == NULL) { + (*env)->DeleteGlobalRef(env, gc); + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + return; + } + // later the graphicsConfig will be used for deallocation of oglsdo + oglsdo->graphicsConfig = gc; + + wglsdo = (WGLSDOps *)malloc(sizeof(WGLSDOps)); J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_initOps"); @@ -160,33 +177,6 @@ } /** - * Returns a pointer (as a jlong) to the native WGLGraphicsConfigInfo - * associated with the given OGLSDOps. This method can be called from - * shared code to retrieve the native GraphicsConfig data in a platform- - * independent manner. - */ -jlong -OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo) -{ - WGLSDOps *wglsdo; - - if (oglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "OGLSD_GetNativeConfigInfo: ops are null"); - return 0L; - } - - wglsdo = (WGLSDOps *)oglsdo->privOps; - if (wglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "OGLSD_GetNativeConfigInfo: wgl ops are null"); - return 0L; - } - - return ptr_to_jlong(wglsdo->configInfo); -} - -/** * Makes the given GraphicsConfig's context current to its associated * "scratch" surface. If there is a problem making the context current, * this method will return NULL; otherwise, returns a pointer to the diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/security/krb5/NativeCreds.c openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/security/krb5/NativeCreds.c --- openjdk-8-8u232-b09/=unpacked-tar7=/src/windows/native/sun/security/krb5/NativeCreds.c 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/src/windows/native/sun/security/krb5/NativeCreds.c 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -404,6 +404,8 @@ "(Lsun/security/krb5/internal/Ticket;" "Lsun/security/krb5/PrincipalName;" "Lsun/security/krb5/PrincipalName;" + "Lsun/security/krb5/PrincipalName;" + "Lsun/security/krb5/PrincipalName;" "Lsun/security/krb5/EncryptionKey;" "Lsun/security/krb5/internal/TicketFlags;" "Lsun/security/krb5/internal/KerberosTime;" @@ -665,7 +667,9 @@ krbcredsConstructor, ticket, clientPrincipal, + NULL, targetPrincipal, + NULL, encryptionKey, ticketFlags, authTime, // mdu diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java openjdk-8-8u242-b08/=unpacked-tar7=/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, Red Hat, Inc. + * Copyright (c) 2015, Oracle, 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 @@ -24,7 +25,14 @@ /* * @test * @bug 8069072 - * @summary Test vectors for com.sun.crypto.provider.GHASH + * @summary Test vectors for com.sun.crypto.provider.GHASH. + * + * Single iteration to verify software-only GHASH algorithm. + * @run main TestGHASH + * + * Multi-iteration to verify test intrinsics GHASH, if available. + * Many iterations are needed so we are sure hotspot will use intrinsic + * @run main TestGHASH -n 10000 */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -124,43 +132,55 @@ public static void main(String[] args) throws Exception { TestGHASH test; - if (args.length == 0) { - test = new TestGHASH("com.sun.crypto.provider.GHASH"); - } else { - test = new TestGHASH(args[0]); - } - - // Test vectors from David A. McGrew, John Viega, - // "The Galois/Counter Mode of Operation (GCM)", 2005. - // - - test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "", - "00000000000000000000000000000000"); - test.check(2, - "66e94bd4ef8a2c3b884cfa59ca342b2e", "", - "0388dace60b6a392f328c2b971b2fe78", - "f38cbb1ad69223dcc3457ae5b6b0f885"); - test.check(3, - "b83b533708bf535d0aa6e52980d53b78", "", - "42831ec2217774244b7221b784d0d49c" + - "e3aa212f2c02a4e035c17e2329aca12e" + - "21d514b25466931c7d8f6a5aac84aa05" + - "1ba30b396a0aac973d58e091473f5985", - "7f1b32b81b820d02614f8895ac1d4eac"); - test.check(4, - "b83b533708bf535d0aa6e52980d53b78", - "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", - "42831ec2217774244b7221b784d0d49c" + - "e3aa212f2c02a4e035c17e2329aca12e" + - "21d514b25466931c7d8f6a5aac84aa05" + - "1ba30b396a0aac973d58e091", - "698e57f70e6ecc7fd9463b7260a9ae5f"); - test.check(5, "b83b533708bf535d0aa6e52980d53b78", - "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", - "61353b4c2806934a777ff51fa22a4755" + - "699b2a714fcdc6f83766e5f97b6c7423" + - "73806900e49f24b22b097544d4896b42" + - "4989b5e1ebac0f07c23f4598", - "df586bb4c249b92cb6922877e444d37b"); + String test_class = "com.sun.crypto.provider.GHASH"; + int i = 0; + int num_of_loops = 1; + while (args.length > i) { + if (args[i].compareTo("-c") == 0) { + test_class = args[++i]; + } else if (args[i].compareTo("-n") == 0) { + num_of_loops = Integer.parseInt(args[++i]); + } + i++; + } + + System.out.println("Running " + num_of_loops + " iterations."); + test = new TestGHASH(test_class); + i = 0; + + while (num_of_loops > i) { + // Test vectors from David A. McGrew, John Viega, + // "The Galois/Counter Mode of Operation (GCM)", 2005. + // + test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "", + "00000000000000000000000000000000"); + test.check(2, + "66e94bd4ef8a2c3b884cfa59ca342b2e", "", + "0388dace60b6a392f328c2b971b2fe78", + "f38cbb1ad69223dcc3457ae5b6b0f885"); + test.check(3, + "b83b533708bf535d0aa6e52980d53b78", "", + "42831ec2217774244b7221b784d0d49c" + + "e3aa212f2c02a4e035c17e2329aca12e" + + "21d514b25466931c7d8f6a5aac84aa05" + + "1ba30b396a0aac973d58e091473f5985", + "7f1b32b81b820d02614f8895ac1d4eac"); + test.check(4, + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "42831ec2217774244b7221b784d0d49c" + + "e3aa212f2c02a4e035c17e2329aca12e" + + "21d514b25466931c7d8f6a5aac84aa05" + + "1ba30b396a0aac973d58e091", + "698e57f70e6ecc7fd9463b7260a9ae5f"); + test.check(5, "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "61353b4c2806934a777ff51fa22a4755" + + "699b2a714fcdc6f83766e5f97b6c7423" + + "73806900e49f24b22b097544d4896b42" + + "4989b5e1ebac0f07c23f4598", + "df586bb4c249b92cb6922877e444d37b"); + i++; + } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/com/sun/tools/attach/StartManagementAgent.java openjdk-8-8u242-b08/=unpacked-tar7=/test/com/sun/tools/attach/StartManagementAgent.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/com/sun/tools/attach/StartManagementAgent.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/com/sun/tools/attach/StartManagementAgent.java 2020-01-15 20:05:09.000000000 +0000 @@ -93,7 +93,7 @@ } catch(AttachOperationFailedException ex) { // We expect parsing of "apa" above to fail, but if the file path // can't be read we get a different exception message - if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) { + if (!ex.getMessage().contains("NumberFormatException: For input string: \"apa\"")) { throw ex; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/GlyphVector/GlyphVectorOutline.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/GlyphVector/GlyphVectorOutline.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/GlyphVector/GlyphVectorOutline.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/GlyphVector/GlyphVectorOutline.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 Google 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.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineBreakMeasurer; +import java.awt.font.TextAttribute; +import java.awt.font.TextLayout; +import java.awt.image.BufferedImage; +import java.io.File; +import java.text.AttributedString; + +import javax.imageio.ImageIO; + +/** + * Manual test for: + * JDK-8057986: freetype code to get glyph outline does not handle initial control point properly + * + * Manual repro recipe: + * (cd test/java/awt/font/GlyphVector/ && javac GlyphVectorOutline.java && wget -q -O/tmp/msgothic.ttc https://browserlinux-jp.googlecode.com/files/msgothic.ttc && java GlyphVectorOutline /tmp/msgothic.ttc /tmp/katakana.png) + * + * Then examine the two rendered Japanese characters in the png file. + * + * Renders text to a PNG by + * 1. using the native Graphics2D#drawGlyphVector implementation + * 2. filling in the result of GlyphVector#getOutline + * + * Should be the same but is different for some CJK characters + * (e.g. Katakana character \u30AF). + * + * @author ikopylov@google.com (Igor Kopylov) + */ +public class GlyphVectorOutline { + public static void main(String[] args) throws Exception { + if (args.length != 2) { + throw new Error("Usage: java GlyphVectorOutline fontfile outputfile"); + } + writeImage(new File(args[0]), + new File(args[1]), + "\u30AF"); + } + + public static void writeImage(File fontFile, File outputFile, String value) throws Exception { + BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + g.setColor(Color.WHITE); + g.fillRect(0, 0, image.getWidth(), image.getHeight()); + g.setColor(Color.BLACK); + + Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile); + font = font.deriveFont(Font.PLAIN, 72f); + FontRenderContext frc = new FontRenderContext(null, false, false); + GlyphVector gv = font.createGlyphVector(frc, value); + g.drawGlyphVector(gv, 10, 80); + g.fill(gv.getOutline(10, 180)); + ImageIO.write(image, "png", outputFile); + } + + private static void drawString(Graphics2D g, Font font, String value, float x, float y) { + AttributedString str = new AttributedString(value); + str.addAttribute(TextAttribute.FOREGROUND, Color.BLACK); + str.addAttribute(TextAttribute.FONT, font); + FontRenderContext frc = new FontRenderContext(null, true, true); + TextLayout layout = new LineBreakMeasurer(str.getIterator(), frc).nextLayout(Integer.MAX_VALUE); + layout.draw(g, x, y); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/Rotate/RotatedFontMetricsTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/Rotate/RotatedFontMetricsTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/Rotate/RotatedFontMetricsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/Rotate/RotatedFontMetricsTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test RotatedFontMetricsTest + * @bug 8139178 + * @summary This test verifies that rotation does not affect font metrics. + * @run main RotatedFontMetricsTest + */ + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class RotatedFontMetricsTest { + static final int FONT_SIZE = Integer.getInteger("font.size", 20); + + public static void main(String ... args) { + Font font = new Font(Font.DIALOG, Font.PLAIN, FONT_SIZE); + Graphics2D g2d = createGraphics(); + + FontMetrics ref = null; + RuntimeException failure = null; + for (int a = 0; a < 360; a += 15) { + Graphics2D g = (Graphics2D)g2d.create(); + g.rotate(Math.toRadians(a)); + FontMetrics m = g.getFontMetrics(font); + g.dispose(); + + boolean status = true; + if (ref == null) { + ref = m; + } else { + status = ref.getAscent() == m.getAscent() && + ref.getDescent() == m.getDescent() && + ref.getLeading() == m.getLeading() && + ref.getMaxAdvance() == m.getMaxAdvance(); + } + + System.out.printf("Metrics a%d, d%d, l%d, m%d (%d) %s\n", + m.getAscent(), m.getDescent(), m.getLeading(), m.getMaxAdvance(), + (int)a, status ? "OK" : "FAIL"); + + if (!status && failure == null) { + failure = new RuntimeException("Font metrics differ for angle " + a); + } + } + if (failure != null) { + throw failure; + } + System.out.println("done"); + } + + private static Graphics2D createGraphics() { + BufferedImage dst = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + return dst.createGraphics(); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/TextLayout/HangulShapingTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/TextLayout/HangulShapingTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/TextLayout/HangulShapingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/TextLayout/HangulShapingTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,72 @@ +// Copyright 2019 Azul Systems, Inc. All Rights Reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 only, as published by +// the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more +// details (a copy is included in the LICENSE file that accompanied this code). +// +// You should have received a copy of the GNU General Public License version 2 +// along with this work; if not, write to the Free Software Foundation, Inc., +// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale, +// CA 94089 USA or visit www.azul.com if you need additional information or +// have any questions. + +import java.awt.Font; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/* + * @test + * @bug 8215210 + * @summary Downport of prr's fix to a certain ICU wrong condition breaking some Hangul shaping + * @run main/othervm -Dsun.font.layoutengine=icu HangulShapingTest + */ +public class HangulShapingTest { + public static void main(String args[]) { + if (!System.getProperty("os.name").startsWith("Mac")) { + return; + } + + // images of the strings as drawn should be identical + String beforeString = "\u1100\u1161 \u1102\u1161"; + String afterString = "\uAC00 \uB098"; + int w = 100, h = 100; + + BufferedImage bi1 = drawit(w, h, beforeString); + BufferedImage bi2 = drawit(w, h, afterString); + + boolean same = true; + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int c1 = bi1.getRGB(x, y); + int c2 = bi2.getRGB(x, y); + same &= (c1 == c2); + } + if (!same) { + break; + } + } + if (!same) { + throw new RuntimeException("Images differ"); + } + } + private static BufferedImage drawit(int w, int h, String toDraw) { + BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics2D biGraphics = bi.createGraphics(); + biGraphics.setColor(Color.white); + biGraphics.fillRect(0, 0, w, h); + biGraphics.setColor(Color.black); + Font font = new Font("Dialog", Font.PLAIN, 20); + biGraphics.setFont(font); + biGraphics.drawString(toDraw, 10, 40); + return bi; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/TextLayout/HebrewIsRTLTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/TextLayout/HebrewIsRTLTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/font/TextLayout/HebrewIsRTLTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/font/TextLayout/HebrewIsRTLTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,75 @@ +// Copyright 2019 Azul Systems, Inc. All Rights Reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 only, as published by +// the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more +// details (a copy is included in the LICENSE file that accompanied this code). +// +// You should have received a copy of the GNU General Public License version 2 +// along with this work; if not, write to the Free Software Foundation, Inc., +// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale, +// CA 94089 USA or visit www.azul.com if you need additional information or +// have any questions. + +import java.awt.Font; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/* + * @test + * @summary Fix to 8215210 should not break RTL with AAT fonts. + * @run main/othervm -Dsun.font.layoutengine=icu HebrewIsRTLTest + */ +public class HebrewIsRTLTest { + static final String hebrewString = "\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599 . \u05E9\u0599\u05E9\u05A1\u05E9\u0595\u05E9\u0593"; + public static void main(String args[]) { + if (!System.getProperty("os.name").startsWith("Mac")) { + return; + } + + // calculate text size + BufferedImage biMetrics = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB); + Graphics2D biMetricsGraphics = biMetrics.createGraphics(); + Font font = new Font("TimesRoman", Font.PLAIN, 40); + biMetricsGraphics.setFont(font); + int width = biMetricsGraphics.getFontMetrics().stringWidth(hebrewString); + int height = biMetricsGraphics.getFontMetrics().getHeight(); + + // create minimal image + BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D biGraphics = bi.createGraphics(); + biGraphics.setColor(Color.white); + biGraphics.fillRect(0, 0, width, height); + biGraphics.setColor(Color.black); + biGraphics.setFont(font); + biGraphics.drawString(hebrewString, 0, height); + + int y = bi.getHeight() / 2; + int x; + int rgb, rgbLeftCount = 0, rgbRightCount = 0; + + for (x = 0; x < bi.getWidth()/2; x++) { + rgb = bi.getRGB(x, y); + if (rgb == Color.BLACK.getRGB()) { + rgbLeftCount++; + } + } + for (x = bi.getWidth()/2 + 1; x < bi.getWidth(); x++) { + rgb = bi.getRGB(x, y); + if (rgb == Color.BLACK.getRGB()) { + rgbRightCount++; + } + } + if (rgbLeftCount > rgbRightCount) { + throw new RuntimeException("Hebrew text seems drawn LTR"); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/GraphicsDevice/CheckDisplayModes.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/GraphicsDevice/CheckDisplayModes.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/GraphicsDevice/CheckDisplayModes.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/GraphicsDevice/CheckDisplayModes.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8007146 + * @bug 8007146 8213119 * @summary [macosx] Setting a display mode crashes JDK under VNC * @author Alexander Scherbatiy * @run main CheckDisplayModes @@ -36,27 +36,28 @@ public static void main(String[] args) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice graphicDevice = ge.getDefaultScreenDevice(); - if (!graphicDevice.isDisplayChangeSupported()) { - System.err.println("Display mode change is not supported on this host. Test is considered passed."); - return; - } - DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode(); - checkDisplayMode(defaultDisplayMode); - graphicDevice.setDisplayMode(defaultDisplayMode); - - DisplayMode[] displayModes = graphicDevice.getDisplayModes(); - boolean isDefaultDisplayModeIncluded = false; - for (DisplayMode displayMode : displayModes) { - checkDisplayMode(displayMode); - graphicDevice.setDisplayMode(displayMode); - if (defaultDisplayMode.equals(displayMode)) { - isDefaultDisplayModeIncluded = true; + for (GraphicsDevice graphicDevice : ge.getScreenDevices()) { + if (!graphicDevice.isDisplayChangeSupported()) { + System.err.println("Display mode change is not supported on this host. Test is considered passed."); + continue; + } + DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode(); + checkDisplayMode(defaultDisplayMode); + graphicDevice.setDisplayMode(defaultDisplayMode); + + DisplayMode[] displayModes = graphicDevice.getDisplayModes(); + boolean isDefaultDisplayModeIncluded = false; + for (DisplayMode displayMode : displayModes) { + checkDisplayMode(displayMode); + graphicDevice.setDisplayMode(displayMode); + if (defaultDisplayMode.equals(displayMode)) { + isDefaultDisplayModeIncluded = true; + } } - } - if (!isDefaultDisplayModeIncluded) { - throw new RuntimeException("Default display mode is not included"); + if (!isDefaultDisplayModeIncluded) { + throw new RuntimeException("Default display mode is not included"); + } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java 2020-01-15 20:05:09.000000000 +0000 @@ -25,10 +25,10 @@ * @test * @bug 7002839 * @summary Static init deadlock Win32GraphicsEnvironment and WToolkit - * @run main/othervm -Djava.awt.headless=true GE_init4 + * @run main/othervm -Djava.awt.headless=true GE_init5 */ -import java.awt.Toolkit; +import java.awt.GraphicsEnvironment; public class GE_init5 { public static void main(String[] args) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/io/Serializable/serialFilter/GlobalFilterTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/io/Serializable/serialFilter/GlobalFilterTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/io/Serializable/serialFilter/GlobalFilterTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/io/Serializable/serialFilter/GlobalFilterTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,9 +42,11 @@ import sun.misc.ObjectInputFilter; /* @test + * @bug 8231422 * @build GlobalFilterTest SerialFilterTest * @run testng/othervm GlobalFilterTest - * @run testng/othervm -Djdk.serialFilter=java.** GlobalFilterTest + * @run testng/othervm -Djdk.serialFilter=java.** + * -Dexpected-jdk.serialFilter=java.** GlobalFilterTest * @run testng/othervm/policy=security.policy GlobalFilterTest * @run testng/othervm/policy=security.policy * -Djava.security.properties=${test.src}/java.security-extra1 @@ -54,6 +56,10 @@ */ @Test public class GlobalFilterTest { + private static final String serialPropName = "jdk.serialFilter"; + private static final String badSerialFilter = "java.lang.StringBuffer;!*"; + private static final String origSerialFilterProperty = + System.setProperty(serialPropName, badSerialFilter); /** * DataProvider of patterns and objects derived from the configured process-wide filter. @@ -62,8 +68,8 @@ @DataProvider(name="globalPatternElements") Object[][] globalPatternElements() { String globalFilter = - System.getProperty("jdk.serialFilter", - Security.getProperty("jdk.serialFilter")); + System.getProperty("expected-" + serialPropName, + Security.getProperty(serialPropName)); if (globalFilter == null) { return new Object[0][]; } @@ -100,12 +106,20 @@ */ @Test() static void globalFilter() { - String pattern = - System.getProperty("jdk.serialFilter", - Security.getProperty("jdk.serialFilter")); ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter(); + + // Check that the System.setProperty(jdk.serialFilter) DOES NOT affect the filter. + String asSetSystemProp = System.getProperty(serialPropName, + Security.getProperty(serialPropName)); + Assert.assertNotEquals(Objects.toString(filter, null), asSetSystemProp, + "System.setProperty(\"jdk.serialfilter\", ...) should not change filter: " + + asSetSystemProp); + + String pattern = + System.getProperty("expected-" + serialPropName, + Security.getProperty(serialPropName)); System.out.printf("global pattern: %s, filter: %s%n", pattern, filter); - Assert.assertEquals(pattern, Objects.toString(filter, null), + Assert.assertEquals(Objects.toString(filter, null), pattern, "process-wide filter pattern does not match"); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/io/Serializable/serialFilter/security.policy openjdk-8-8u242-b08/=unpacked-tar7=/test/java/io/Serializable/serialFilter/security.policy --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/io/Serializable/serialFilter/security.policy 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/io/Serializable/serialFilter/security.policy 2020-01-15 20:05:09.000000000 +0000 @@ -3,7 +3,7 @@ // Specific permission under test permission java.security.SerializablePermission "serialFilter"; // Permissions needed to run the test - permission java.util.PropertyPermission "*", "read"; + permission java.util.PropertyPermission "*", "read,write"; permission java.io.FilePermission "<>", "read,write,delete"; permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.security.SecurityPermission "*"; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * 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,18 @@ * @test * @summary Test consistent parsing of ex-RUNTIME annotations that * were changed and separately compiled to have CLASS retention + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main AnnotationTypeRuntimeAssumptionTest */ -import sun.misc.IOUtils; - import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import jdk.testlibrary.IOUtils; + import static java.lang.annotation.RetentionPolicy.CLASS; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -137,7 +140,7 @@ String altPath = altName.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(altPath)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); // patch class bytes to contain original name for (int i = 0; i < bytes.length - 2; i++) { if (bytes[i] == '_' && @@ -160,7 +163,7 @@ String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * 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,11 +22,14 @@ */ /* -@test -@bug 8004970 -@summary Lambda serialization in the presence of class loaders -@author Peter Levart -*/ + * @test + * @bug 8004970 + * @summary Lambda serialization in the presence of class loaders + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main LambdaClassLoaderSerialization + * @author Peter Levart + */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -37,6 +40,8 @@ import java.io.Serializable; import java.util.Arrays; +import jdk.testlibrary.IOUtils; + public class LambdaClassLoaderSerialization { public interface SerializableRunnable extends Runnable, Serializable {} @@ -125,7 +130,7 @@ String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = readFully(is); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { throw new ClassNotFoundException(name); @@ -135,30 +140,5 @@ throw new ClassNotFoundException(name, e); } } - - static byte[] readFully(InputStream is) throws IOException { - byte[] output = {}; - int pos = 0; - while (true) { - int bytesToRead; - if (pos >= output.length) { // Only expand when there's no room - bytesToRead = output.length + 1024; - if (output.length < pos + bytesToRead) { - output = Arrays.copyOf(output, pos + bytesToRead); - } - } else { - bytesToRead = output.length - pos; - } - int cc = is.read(output, pos, bytesToRead); - if (cc < 0) { - if (output.length != pos) { - output = Arrays.copyOf(output, pos); - } - break; - } - pos += cc; - } - return output; - } } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/ProcessBuilder/Basic.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/ProcessBuilder/Basic.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/ProcessBuilder/Basic.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/ProcessBuilder/Basic.java 2020-01-15 20:05:09.000000000 +0000 @@ -61,6 +61,15 @@ /* used for AIX only */ static final String libpath = System.getenv("LIBPATH"); + /** + * Returns the number of milliseconds since time given by + * startNanoTime, which must have been previously returned from a + * call to {@link System.nanoTime()}. + */ + private static long millisElapsedSince(long startNanoTime) { + return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); + } + private static String commandOutput(Reader r) throws Throwable { StringBuilder sb = new StringBuilder(); int c; @@ -2294,40 +2303,98 @@ //---------------------------------------------------------------- // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) - // interrupt works as expected. + // interrupt works as expected, if interrupted while waiting. //---------------------------------------------------------------- try { List childArgs = new ArrayList(javaChildArgs); childArgs.add("sleep"); final Process p = new ProcessBuilder(childArgs).start(); final long start = System.nanoTime(); - final CountDownLatch ready = new CountDownLatch(1); - final CountDownLatch done = new CountDownLatch(1); + final CountDownLatch aboutToWaitFor = new CountDownLatch(1); final Thread thread = new Thread() { public void run() { try { - final boolean result; - try { - ready.countDown(); - result = p.waitFor(30000, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - return; - } + aboutToWaitFor.countDown(); + Thread.currentThread().interrupt(); + boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS); fail("waitFor() wasn't interrupted, its return value was: " + result); - } catch (Throwable t) { - unexpected(t); - } finally { - done.countDown(); - } + } catch (InterruptedException success) { + } catch (Throwable t) { unexpected(t); } + } + }; + + thread.start(); + aboutToWaitFor.await(); + thread.interrupt(); + thread.join(10L * 1000L); + check(millisElapsedSince(start) < 10L * 1000L); + check(!thread.isAlive()); + p.destroy(); + } catch (Throwable t) { unexpected(t); } + + //---------------------------------------------------------------- + // Check that Process.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS) + // interrupt works as expected, if interrupted while waiting. + //---------------------------------------------------------------- + try { + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("sleep"); + final Process p = new ProcessBuilder(childArgs).start(); + final long start = System.nanoTime(); + final CountDownLatch aboutToWaitFor = new CountDownLatch(1); + + final Thread thread = new Thread() { + public void run() { + try { + aboutToWaitFor.countDown(); + Thread.currentThread().interrupt(); + boolean result = p.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS); + fail("waitFor() wasn't interrupted, its return value was: " + result); + } catch (InterruptedException success) { + } catch (Throwable t) { unexpected(t); } + } + }; + + thread.start(); + aboutToWaitFor.await(); + thread.interrupt(); + thread.join(10L * 1000L); + check(millisElapsedSince(start) < 10L * 1000L); + check(!thread.isAlive()); + p.destroy(); + } catch (Throwable t) { unexpected(t); } + + //---------------------------------------------------------------- + // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) + // interrupt works as expected, if interrupted before waiting. + //---------------------------------------------------------------- + try { + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("sleep"); + final Process p = new ProcessBuilder(childArgs).start(); + final long start = System.nanoTime(); + final CountDownLatch threadStarted = new CountDownLatch(1); + + final Thread thread = new Thread() { + public void run() { + try { + threadStarted.countDown(); + do { Thread.yield(); } + while (!Thread.currentThread().isInterrupted()); + boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS); + fail("waitFor() wasn't interrupted, its return value was: " + result); + } catch (InterruptedException success) { + } catch (Throwable t) { unexpected(t); } } }; thread.start(); - ready.await(); - Thread.sleep(1000); + threadStarted.await(); thread.interrupt(); - done.await(); + thread.join(10L * 1000L); + check(millisElapsedSince(start) < 10L * 1000L); + check(!thread.isAlive()); p.destroy(); } catch (Throwable t) { unexpected(t); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * 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,9 @@ * @summary Test that a static method on an interface doesn't hide a default * method with the same name and signature in a separate compilation * scenario. + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main StaticInterfaceMethodInWayOfDefault */ import java.io.IOException; @@ -35,7 +38,7 @@ import java.lang.reflect.Method; import java.util.concurrent.Callable; -import sun.misc.IOUtils; +import jdk.testlibrary.IOUtils; public class StaticInterfaceMethodInWayOfDefault { public interface A_v1 { @@ -144,7 +147,7 @@ String altPath = altName.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(altPath)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); // patch class bytes to contain original name for (int i = 0; i < bytes.length - 2; i++) { if (bytes[i] == '_' && @@ -167,7 +170,7 @@ String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8231584 + * @library /lib/testlibrary + * @run main/othervm LoadLibraryTest + */ + +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.Path; +import java.net.MalformedURLException; +import java.net.URLClassLoader; +import java.net.URL; + +public class LoadLibraryTest { + static Thread thread1 = null; + static Thread thread2 = null; + + static volatile boolean thread1Ready = false; + + private static final String TEST_SRC = System.getProperty("test.src"); + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + private static final Path CLS_DIR = Paths.get("classes"); + + static TestClassLoader loader; + static void someLibLoad() { + try { +/* + FileSystems.getDefault(); + + // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime) + java.net.NetworkInterface.getNetworkInterfaces(); + + System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); +*/ + Class c = Class.forName("Target2", true, loader); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + static class TestClassLoader extends URLClassLoader { + boolean passed = false; + + public boolean passed() { + return passed; + } + + TestClassLoader() throws MalformedURLException { + super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') }); + } + + public String findLibrary(String name) { + System.out.println("findLibrary " + name); + + if ("someLibrary".equals(name)) { + try { + synchronized(thread1) { + while(!thread1Ready) { + thread1.wait(); + } + thread1.notifyAll(); + } + + Thread.sleep(10000); + + System.out.println("Thread2 load"); + someLibLoad(); + + // no deadlock happened + passed = true; + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + + return super.findLibrary(name); + } + } + + + public static void main(String[] args) throws Exception { + loader = new TestClassLoader(); + + if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) { + throw new Exception("Can't compile"); + } + + thread1 = new Thread() { + public void run() { + try { + synchronized(this) { + thread1Ready = true; + thread1.notifyAll(); + thread1.wait(); + } + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + + System.out.println("Thread1 load"); + someLibLoad(); + }; + }; + + thread2 = new Thread() { + public void run() { + try { + Class c = Class.forName("Target", true, loader); + System.out.println(c); + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + }; + + thread1.setDaemon(true); + thread2.setDaemon(true); + + thread1.start(); + thread2.start(); + + thread1.join(); + thread2.join(); + + if (!loader.passed()) { + throw new RuntimeException("FAIL"); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target2.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target2.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target2.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target2.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +class Target2 { + static { + System.loadLibrary("awt"); + } +} + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/lang/Runtime/loadLibrary/src/Target.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +class Target { + static { + try { + System.loadLibrary("someLibrary"); + throw new RuntimeException("someLibrary was loaded"); + } catch (UnsatisfiedLinkError e) { + // expected: we do not have a someLibrary + } + } +} + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/net/CookieHandler/B6791927.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/net/CookieHandler/B6791927.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/net/CookieHandler/B6791927.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/net/CookieHandler/B6791927.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,9 @@ /** * @test - * @bug 6791927 + * @bug 6791927 8233886 * @summary Wrong Locale in HttpCookie::expiryDate2DeltaSeconds + * @run main/othervm B6791927 */ import java.net.*; @@ -32,12 +33,14 @@ import java.util.Locale; public class B6791927 { - public static final void main( String[] aaParamters ) throws Exception{ + public static final void main(String[] aaParamters) throws Exception { Locale reservedLocale = Locale.getDefault(); try { // Forces a non US locale Locale.setDefault(Locale.FRANCE); - List cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Sat, 09-Nov-2019 23:12:40 GMT"); + List cookies = HttpCookie.parse("set-cookie:" + + " CUSTOMER=WILE_E_COYOTE;" + + " expires=Sat, 09-Nov-2041 23:12:40 GMT"); if (cookies == null || cookies.isEmpty()) { throw new RuntimeException("No cookie found"); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java 2020-01-15 20:05:09.000000000 +0000 @@ -29,12 +29,12 @@ /** * @test - * @bug 6852744 + * @bug 6852744 8133489 * @summary PIT b61: PKI test suite fails because self signed certificates * are being rejected - * @run main/othervm KeyUsageMatters subca - * @run main/othervm KeyUsageMatters subci - * @run main/othervm KeyUsageMatters alice + * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters subca + * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters subci + * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters alice * @author Xuelei Fan */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/java/security/testlibrary/Proc.java openjdk-8-8u242-b08/=unpacked-tar7=/test/java/security/testlibrary/Proc.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/java/security/testlibrary/Proc.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/java/security/testlibrary/Proc.java 2020-01-15 20:05:09.000000000 +0000 @@ -235,6 +235,13 @@ br = new BufferedReader(new InputStreamReader(p.getInputStream())); return this; } + String getId(String suffix) { + if (debug != null) { + return debug + "." + suffix; + } else { + return System.identityHashCode(this) + "." + suffix; + } + } // Reads a line from stdout of proc public String readLine() throws IOException { String s = br.readLine(); @@ -303,9 +310,13 @@ boolean isEmpty = true; while (true) { int i = System.in.read(); - if (i == -1) break; + if (i == -1) { + break; + } isEmpty = false; - if (i == '\n') break; + if (i == '\n') { + break; + } if (i != 13) { // Force it to a char, so only simple ASCII works. sb.append((char)i); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @key headful + * @bug 8225505 + * @summary CTRL + 1 does not show tooltip message for menu items + * @run main/manual JMenuItemToolTipKeyBindingsTest + */ + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.concurrent.atomic.AtomicBoolean; + +public class JMenuItemToolTipKeyBindingsTest { + private static final long TIMEOUT = 5 * 60 * 1000; + private static final AtomicBoolean testCompleted = new AtomicBoolean(false); + private static volatile boolean testResult = false; + + private static Dialog controlDialog; + private static JFrame testFrame; + + private static final String instructions = + "Verify that \"CTRL\" + \"F1\" key sequence shows/hides tool tip message" + + "\nfor menu items.\n" + + "\n1. Open pop-up menu \"Menu\", (i.e. press \"F10\")." + + "\n2. Navigate to some menu element using keyboard." + + "\n3. Press \"CTRL\" + \"F1\" once menu item is selected." + + "\nIf tooltip message is displayed for the item then press \"Pass\"," + + "\n otherwise press \"Fail\"."; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> createAndShowGUI()); + + waitForCompleting(); + if (!testResult) { + throw new RuntimeException("Test FAILED!"); + } + } finally { + if (controlDialog != null) { + controlDialog.dispose(); + } + if (testFrame != null) { + testFrame.dispose(); + } + } + } + + private static void createAndShowGUI() { + controlDialog = new Dialog((JFrame)null, "JMenuItemToolTipKeyBindingsTest"); + + TextArea messageArea = new TextArea(instructions, 15, 80, TextArea.SCROLLBARS_BOTH); + controlDialog.add("North", messageArea); + + Button passedButton = new Button("Pass"); + passedButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + testResult = true; + completeTest(); + } + }); + + Button failedButton = new Button("Fail"); + failedButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + testResult = false; + completeTest(); + } + }); + + Panel buttonPanel = new Panel(); + buttonPanel.add("West",passedButton); + buttonPanel.add("East", failedButton); + controlDialog.add("South", buttonPanel); + + controlDialog.setBounds(250, 0, 500, 500); + controlDialog.setVisible(true); + + testFrame = new JFrame("JMenuItemToolTipKeyBindingsTest"); + testFrame.setSize(200, 200); + JMenuBar jMenuBar = new JMenuBar(); + JMenu jMenu = new JMenu("Menu"); + for (int i = 0; i < 3; i++) { + JMenuItem jMenuItem = new JMenuItem("Item " + i); + jMenuItem.setToolTipText("Tooltip " + i); + jMenu.add(jMenuItem); + } + jMenuBar.add(jMenu); + testFrame.setJMenuBar(jMenuBar); + testFrame.setVisible(true); + } + + private static void completeTest() { + testCompleted.set(true); + synchronized (testCompleted) { + testCompleted.notifyAll(); + } + } + + private static void waitForCompleting() throws Exception { + synchronized (testCompleted) { + long startTime = System.currentTimeMillis(); + while (!testCompleted.get()) { + testCompleted.wait(TIMEOUT); + if (System.currentTimeMillis() - startTime >= TIMEOUT) { + break; + } + } + } + } +} + diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/ClassFileInstaller.java openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/ClassFileInstaller.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/ClassFileInstaller.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/ClassFileInstaller.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -21,28 +21,229 @@ * questions. */ +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileNotFoundException; import java.io.InputStream; +import java.io.ByteArrayInputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** - * Dump a class file for a class on the class path in the current directory + * Dump a class file for a class on the class path in the current directory, or + * in the specified JAR file. This class is usually used when you build a class + * from a test library, but want to use this class in a sub-process. + * + * For example, to build the following library class: + * test/lib/sun/hotspot/WhiteBox.java + * + * You would use the following tags: + * + * @library /test/lib + * @build sun.hotspot.WhiteBox + * + * JTREG would build the class file under + * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class + * + * With you run your main test class using "@run main MyMainClass", JTREG would setup the + * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to + * load the WhiteBox class. + * + * However, if you run a sub process, and do not wish to use the exact same -classpath, + * You can use ClassFileInstaller to ensure that WhiteBox is available in the current + * directory of your test: + * + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * + * Or, you can use the -jar option to store the class in the specified JAR file. If a relative + * path name is given, the JAR file would be relative to the current directory of + * + * @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox */ public class ClassFileInstaller { /** + * You can enable debug tracing of ClassFileInstaller by running JTREG with + * jtreg -DClassFileInstaller.debug=true ... + */ + public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug"); + + /** * @param args The names of the classes to dump * @throws Exception */ public static void main(String... args) throws Exception { - for (String arg : args) { - ClassLoader cl = ClassFileInstaller.class.getClassLoader(); + if (args.length > 1 && args[0].equals("-jar")) { + if (args.length < 2) { + throw new RuntimeException("Usage: ClassFileInstaller \n" + + "where possible options include:\n" + + " -jar Write to the JAR file "); + } + writeJar(args[1], null, args, 2, args.length); + } else { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); + } + for (String arg : args) { + writeClassToDisk(arg); + } + } + } + + public static class Manifest { + private InputStream in; + + private Manifest(InputStream in) { + this.in = in; + } + + static Manifest fromSourceFile(String fileName) throws Exception { + String pathName = System.getProperty("test.src") + File.separator + fileName; + return new Manifest(new FileInputStream(pathName)); + } + + // Example: + // String manifest = "Premain-Class: RedefineClassHelper\n" + + // "Can-Redefine-Classes: true\n"; + // ClassFileInstaller.writeJar("redefineagent.jar", + // ClassFileInstaller.Manifest.fromString(manifest), + // "RedefineClassHelper"); + static Manifest fromString(String manifest) throws Exception { + return new Manifest(new ByteArrayInputStream(manifest.getBytes())); + } + + public InputStream getInputStream() { + return in; + } + } + + private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile)); + } + + (new File(jarFile)).delete(); + FileOutputStream fos = new FileOutputStream(jarFile); + ZipOutputStream zos = new ZipOutputStream(fos); + + // The manifest must be the first or second entry. See comments in JarInputStream + // constructor and JDK-5046178. + if (manifest != null) { + writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream()); + } + + for (int i=from; i 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, is); + } + + public static void writeClassToDisk(String className, byte[] bytecode) throws Exception { + writeClassToDisk(null, className, bytecode); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception { + writeClassToDisk(zos, className, bytecode, ""); + } + + public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception { + writeClassToDisk(null, className, bytecode, prependPath); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception { + // Convert dotted class name to a path to a class file + String pathName = className.replace('.', '/').concat(".class"); + if (prependPath.length() > 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode)); + } + + private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing " + pathName); + } + if (zos != null) { + ZipEntry ze = new ZipEntry(pathName); + zos.putNextEntry(ze); + byte[] buf = new byte[1024]; + int len; + while ((len = is.read(buf))>0){ + zos.write(buf, 0, len); + } + } else { // Create the class file's package directory Path p = Paths.get(pathName); Path parent = p.getParent(); @@ -52,5 +253,6 @@ // Create the class file Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); } + is.close(); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/FileUtils.java openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/FileUtils.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/FileUtils.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/FileUtils.java 2020-01-15 20:05:09.000000000 +0000 @@ -228,4 +228,3 @@ return areFileSystemsAccessible; } } - diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/IOUtils.java openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/IOUtils.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/IOUtils.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/lib/testlibrary/jdk/testlibrary/IOUtils.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.testlibrary; + +/** + * Defines useful I/O methods. + */ +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +public final class IOUtils { + + /* + * Prevent instantiation. + */ + private IOUtils() {} + + /** + * Read all bytes from in + * until EOF is detected. + * @param in input stream, must not be null + * @return bytes read + * @throws IOException Any IO error. + */ + public static byte[] readFully(InputStream is) throws IOException { + byte[] output = {}; + int pos = 0; + while (true) { + int bytesToRead; + if (pos >= output.length) { // Only expand when there's no room + bytesToRead = output.length + 1024; + if (output.length < pos + bytesToRead) { + output = Arrays.copyOf(output, pos + bytesToRead); + } + } else { + bytesToRead = output.length - pos; + } + int cc = is.read(output, pos, bytesToRead); + if (cc < 0) { + if (output.length != pos) { + output = Arrays.copyOf(output, pos); + } + break; + } + pos += cc; + } + return output; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/ProblemList.txt openjdk-8-8u242-b08/=unpacked-tar7=/test/ProblemList.txt --- openjdk-8-8u232-b09/=unpacked-tar7=/test/ProblemList.txt 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/ProblemList.txt 2020-01-15 20:05:09.000000000 +0000 @@ -270,6 +270,9 @@ # 8026976 sun/security/pkcs11/ec/TestKeyFactory.java generic-all +# 8180837 +sun/security/pkcs11/Secmod/AddTrustedCert.java generic-all +sun/security/pkcs11/tls/TestKeyMaterial.java generic-all # 7164518 sun/security/krb5/auto/Unreachable.java macosx-all diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8233223 + * @summary Interoperability tests with Amazon's CA1, CA2, CA3, and CA4 + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath AmazonCA OCSP + * @run main/othervm -Djava.security.debug=certpath AmazonCA CRL + */ + +/* + * Obtain TLS test artifacts for Amazon CAs from: + * + * Amazon Root CA 1 + * Valid - https://good.sca1a.amazontrust.com/ + * Revoked - https://revoked.sca1a.amazontrust.com/ + * Amazon Root CA 2 + * Valid - https://good.sca2a.amazontrust.com/ + * Revoked - https://revoked.sca2a.amazontrust.com/ + * Amazon Root CA 3 + * Valid - https://good.sca3a.amazontrust.com/ + * Revoked - https://revoked.sca3a.amazontrust.com/ + * Amazon Root CA 4 + * Valid - https://good.sca4a.amazontrust.com/ + * Revoked - https://revoked.sca4a.amazontrust.com/ + */ +public class AmazonCA { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + boolean ocspEnabled = false; + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + ocspEnabled = true; + } + + new AmazonCA_1().runTest(pathValidator, ocspEnabled); + new AmazonCA_2().runTest(pathValidator, ocspEnabled); + new AmazonCA_3().runTest(pathValidator, ocspEnabled); + new AmazonCA_4().runTest(pathValidator, ocspEnabled); + } +} + +class AmazonCA_1 { + + // Owner: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US + // Serial number: 67f9457508c648c09ca652e71791830e72592 + // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIERzCCAy+gAwIBAgITBn+UV1CMZIwJymUucXkYMOclkjANBgkqhkiG9w0BAQsF\n" + + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + + "b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" + + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" + + "IDFBMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + + "AoIBAQCeQM3XCsIZunv8bSJxOqkc/ed87uL76FDB7teBNThDRB+1J7aITuadbNfH\n" + + "5ZfZykrdZ1qQLKxP6DwHOmJr9u2b4IxjUX9qUMuq4B02ghD2g6yU3YivEosZ7fpo\n" + + "srD2TBN29JpgPGrOrpOE+ArZuIpBjdKFinemu6fTDD0NCeQlfyHXd1NOYyfYRLTa\n" + + "xlpDqr/2M41BgSkWQfSPHHyRWNQgWBiGsIQaS8TK0g8OWi1ov78+2K9DWT+AHgXW\n" + + "AanjZK91GfygPXJYSlAGxSiBAwH/KhAMifhaoFYAbH0Yuohmd85B45G2xVsop4TM\n" + + "Dsl007U7qnS7sdJ4jYGzEvva/a95AgMBAAGjggE5MIIBNTASBgNVHRMBAf8ECDAG\n" + + "AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUYtRCXoZwdWqQvMa40k1g\n" + + "wjS6UTowHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH\n" + + "AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy\n" + + "dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy\n" + + "dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js\n" + + "LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBEGA1UdIAQKMAgw\n" + + "BgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAMHbSWHRFMzGNIE0qhN6gnRahTrTU\n" + + "CDPwe7l9/q0IA+QBlrpUHnlAreetYeH1jB8uF3qXXzy22gpBU7NqulTkqSPByT1J\n" + + "xOhpT2FpO5R3VAdMPdWfSEgtrED0jkmyUQrR1T+/A+nBLdJZeQcl+OqLgeY790JM\n" + + "JJTsJnnI6FBWeTGhcDI4Y+n3KS3QCVePeWI7jx1dhrHcXH+QDX8Ywe31hV7YENdr\n" + + "HDpUXrjK6eHN8gazy8G6pndXHFwHp4auiZbJbYAk/q1peOTRagD2JojcLkm+i3cD\n" + + "843t4By6YT/PVlePU2PCWejkrJQnKQAPOov7IA8kuO2RDWuzE/zF6Hotdg==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=good.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US + // Serial number: 703e4e4bbd78e2b6db5634f36c4ee944cb1a4 + // Valid from: Mon Jul 29 16:53:36 PDT 2019 until: Sat Aug 29 16:53:36 PDT 2020 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIFEzCCA/ugAwIBAgITBwPk5LvXjitttWNPNsTulEyxpDANBgkqhkiG9w0BAQsF\n" + + "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + + "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzUzMzZaFw0yMDA4\n" + + "MjkyMzUzMzZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + + "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" + + "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" + + "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" + + "czEjMCEGA1UEAxMaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wggEiMA0GCSqG\n" + + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQyuJ83c2Zf9k29f6iLqd8nJSuHSk1v+SS\n" + + "0sYyG8tjscfCC1HcOdNj37vtiNN65sXh/e/kBKH9wvzhCLOJbBqVKRHOZuHdJEpH\n" + + "35R6C/PbcV/tp49g6mNmBe+lcmm/cwwCtYvkL0rgL/OKB0liFhhRIqy2TPg08op/\n" + + "RlY2DdbgBA2B3g7wdMo0hK3SO56/QUccUtLRm43km9Yd4E3U+CEUyDd0Bmc/YbPa\n" + + "htuXVsXJwiwlwooomujIIENhFw3htdcsu2apRj8EYUrKL8Mvvn+h16gDyobj0f01\n" + + "jWXlUgmH2lzUzca5eGuphfvmWN/ME/yqC2mMvWGnWySycqtT8VdJAgMBAAGjggFj\n" + + "MIIBXzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFFENOZBwFkjVdQX0iK32c77z\n" + + "SUl6MB8GA1UdIwQYMBaAFGLUQl6GcHVqkLzGuNJNYMI0ulE6MB0GA1UdJQQWMBQG\n" + + "CCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGG\n" + + "IWh0dHA6Ly9vY3NwLnNjYTFhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYq\n" + + "aHR0cDovL2NydC5zY2ExYS5hbWF6b250cnVzdC5jb20vc2NhMWEuY2VyMCUGA1Ud\n" + + "EQQeMByCGmdvb2Quc2NhMWEuYW1hem9udHJ1c3QuY29tMFAGA1UdIARJMEcwDQYL\n" + + "YIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcCARYfaHR0cHM6Ly93d3cu\n" + + "YW1hem9udHJ1c3QuY29tL2NwczANBgkqhkiG9w0BAQsFAAOCAQEAmn7z6Ub1sL77\n" + + "wyUEaCq/Odqm+2RtYYMJ1MeW6nTXTfAgZ/iLx/6hStafd9AK9gHiTCggBpj6KgnF\n" + + "UsGMDeX879jP675fH6SEk710QPDhIrfAzwE0pF/eUNsd7pLwne32zHX0ouCoAt4d\n" + + "KwBCZkKNUkdj4U+bpOJzvtcTP9JlzziLp9IFRjjQh3xKgfblx57CmRJbqH3fT5JJ\n" + + "IAIDVTz3ZUcqhPTFAnNsO1oNBEyrO5X9rwCiSy7aRijY/11R75mIIvyA9zyd9ss1\n" + + "kvrrER0GWMTDvC84FZD2vhkXgPTFrB1Dn9f3QgO5APT9GCFY5hdpqqPEXOSdRzQo\n" + + "h9j4OQAqtA==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US + // Serial number: 6f1d774ad5e7b6d251d217661782bbdb6f37d + // Valid from: Mon Jan 28 15:34:38 PST 2019 until: Thu Apr 28 16:34:38 PDT 2022 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIE2zCCA8OgAwIBAgITBvHXdK1ee20lHSF2YXgrvbbzfTANBgkqhkiG9w0BAQsF\n" + + "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + + "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM0MzhaFw0yMjA0\n" + + "MjgyMzM0MzhaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + + "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" + + "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" + + "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" + + "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTFhLmFtYXpvbnRydXN0LmNvbTCCASIwDQYJ\n" + + "KoZIhvcNAQEBBQADggEPADCCAQoCggEBANUoHop9sW+QlgVsdtacioraTAWHcSTd\n" + + "MNkOkOEMgJIFPyfdcDvW/H2NvpdYeIQqzaCgT2kcsONWTZTPJMirCPnzl1ohHOZU\n" + + "uTnOVkamGxvNmQCURLBXmlCMRTCI5RY3CuYntFFbSPAnbumsF+K/gKqcE6ME53Bw\n" + + "PAwn4qwavB0i5Ib7Jk8XYzxSYXC9l8QLxt6fshPJRlecpXzfmVFvMAm3IbaLcpuv\n" + + "AtD+8I2KwjNtBPRPNYeFsWxwsgUGAyHEGa61oTGUqqAXu5YmPfyK+YTOJdoofsh4\n" + + "Tf3K7AKxnPWuvY3RNTs1pzEVwJYZqSsNwbgyKJJ4+0Xe4iP7qB8SYf8CAwEAAaOC\n" + + "ASkwggElMA4GA1UdDwEB/wQEAwIFoDAdBgNVHQ4EFgQUGHreoz+LP/Wr+RKzuexO\n" + + "V8ICtmEwHwYDVR0jBBgwFoAUYtRCXoZwdWqQvMa40k1gwjS6UTowHQYDVR0lBBYw\n" + + "FAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw\n" + + "AYYhaHR0cDovL29jc3Auc2NhMWEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC\n" + + "hipodHRwOi8vY3J0LnNjYTFhLmFtYXpvbnRydXN0LmNvbS9zY2ExYS5jZXIwKAYD\n" + + "VR0RBCEwH4IdcmV2b2tlZC5zY2ExYS5hbWF6b250cnVzdC5jb20wEwYDVR0gBAww\n" + + "CjAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBABSbe1UCLL7Qay6XK5wD8B5a\n" + + "wvR1XG3UrggpVIz/w5cutEm/yE71hzE0gag/3YPbNYEnaLbJH+9jz4YW9wd/cEPj\n" + + "xSK5PErAQjCd+aA4LKN1xqkSysgYknl0y47hJBXGnWf+hxvBBHeSoUzM0KIC21pC\n" + + "ZyXrmfaPCQAz13ruYIYdQaETqXGVORmKbf/a+Zn18/tfQt0LeeCYVoSopbXWQvcJ\n" + + "gUMtdIqYQmb8aVj0pdZXwKl4yZ2DtlS3Z9MpWNgQNlhRPmiYlu28y2yTtZ9SwD6m\n" + + "2f+cwc19aJrDT4Y280px+jRU7dIE6oZVJU+yBRVIZYpUFAB7extCMVxnTkCf8Dk=\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // EE certificates don't have CRLDP extension + if (!ocspEnabled){ + pathValidator.validate(new String[]{INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + return; + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Jan 28 15:35:56 PST 2019", System.out); + } +} + +class AmazonCA_2 { + + // Owner: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 2, O=Amazon, C=US + // Serial number: 67f945755f187a91f8163f3e624620177ff38 + // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGRzCCBC+gAwIBAgITBn+UV1Xxh6kfgWPz5iRiAXf/ODANBgkqhkiG9w0BAQwF\n" + + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + + "b24gUm9vdCBDQSAyMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" + + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" + + "IDJBMQ8wDQYDVQQDEwZBbWF6b24wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" + + "AoICAQC0P8hSLewmrZ41CCPBQytZs5NBFMq5ztbnMf+kZUp9S25LPfjNW3zgC/6E\n" + + "qCTWNVMMHhq7ez9IQJk48qbfBTLlZkuKnUWbA9vowrDfcxUN0mRE4B/TJbveXyTf\n" + + "vE91iDlqDrERecE9D8sdjzURrtHTp27lZdRkXFvfEVCq4hl3sHkzjodisaQthLp1\n" + + "gLsiA7vKt+8zcL4Aeq52UyYb8r4/jdZ3KaQp8O/T4VwDCRKm8ey3kttpJWaflci7\n" + + "eRzNjY7gE3NMANVXCeQwOBfH2GjINFCObmPsqiBuoAnsv2k5aQLNoU1OZk08ClXm\n" + + "mEZ2rI5qZUTX1HuefBJnpMkPugFCw8afaHnB13SkLE7wxX8SZRdDIe5WiwyDL1tR\n" + + "2+8lpz4JsMoFopHmD3GaHyjbN+hkOqHgLltwewOsiyM0u3CZphypN2KeD+1FLjnY\n" + + "TgdIAd1FRgK2ZXDDrEdjnsSEfShKf0l4mFPSBs9E3U6sLmubDRXKLLLpa/dF4eKu\n" + + "LEKS1bXYT28iM6D5gSCnzho5G4d18jQD/slmc5XmRo5Pig0RyBwDaLuxeIZuiJ0A\n" + + "J6YFhffbrLYF5dEQl0cU+t3VBK5u/o1WkWXsZawU038lWn/AXerodT/pAcrtWA4E\n" + + "NQEN09WEKMhZVPhqdwhF/Gusr04mQtKt7T2v6UMQvtVglv5E7wIDAQABo4IBOTCC\n" + + "ATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYE\n" + + "FNpDStD8AcBLv1gnjHbNCoHzlC70MB8GA1UdIwQYMBaAFLAM8Eww9AVYAkj9M+VS\n" + + "r0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3Au\n" + + "cm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jcnQu\n" + + "cm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9vdGNhMi5jZXIwPwYDVR0fBDgwNjA0\n" + + "oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFtYXpvbnRydXN0LmNvbS9yb290Y2Ey\n" + + "LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggIBAEO5W+iF\n" + + "yChjDyyrmiwFupVWQ0Xy2ReFNQiZq7XKVHvsLQe01moSLnxcBxioOPBKt1KkZO7w\n" + + "Gcbmke0+7AxLaG/F5NPnzRtK1/pRhXQ0XdU8pVh/1/h4GoqRlZ/eN0JDarUhZPkV\n" + + "kSr96LUYDTxcsAidF7zkzWfmtcJg/Aw8mi14xKVEa6aVyKu54c8kKkdlt0WaigOv\n" + + "Z/xYhxp24AfoFKaIraDNdsD8q2N7eDYeN4WGLzNSlil+iFjzflI9mq1hTuI/ZNjV\n" + + "rbvob6FUQ8Cc524gMjbpZCNuZ1gfXzwwhGp0AnQF6CJsWF9uwPpZEVFnnnfiWH3M\n" + + "oup41EvBhqaAqOlny0sm5pI82nRUCAE3DLkJ1+eAtdQaYblZQkQrRyTuPmJEm+5y\n" + + "QwdDVw6uHc5OsSj/tyhh8zJ2Xq3zgh3dMONGjJEysxGaCoIb+61PWwMy2dIarVwI\n" + + "r+c+AY+3PrhgBspNdWZ87JzNHii7ksdjUSVGTTy1vGXgPYrv0lp0IMnKaZP58xiw\n" + + "rDx7uTlQuPVWNOZvCaT3ZcoxTsNKNscIUe+WJjWx5hdzpv/oksDPY5ltZ0j3hlDS\n" + + "D+Itk95/cNJVRM/0HpxI1SX9MTZtOSJoEDdUtOpVaOuBAvEK4gvTzdt0r5L+fuI6\n" + + "o5LAuRo/LO1xVRH49KFRoaznzU3Ch9+kbPb3\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=good.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US + // Serial number: 703e4e70616c90d611fd04a5ecc635665184e + // Valid from: Mon Jul 29 16:54:06 PDT 2019 until: Sat Aug 29 16:54:06 PDT 2020 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIHEzCCBPugAwIBAgITBwPk5wYWyQ1hH9BKXsxjVmUYTjANBgkqhkiG9w0BAQwF\n" + + "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + + "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0MDZaFw0yMDA4\n" + + "MjkyMzU0MDZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + + "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" + + "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" + + "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" + + "czEjMCEGA1UEAxMaZ29vZC5zY2EyYS5hbWF6b250cnVzdC5jb20wggIiMA0GCSqG\n" + + "SIb3DQEBAQUAA4ICDwAwggIKAoICAQC+XjOB3ZCFX+b9y9reP+e6EAQz4ytiMSqU\n" + + "O4s5MyYLkY6n4BIZHmgWeQ2IgW1VrH8ho+Iu3UsTiuhd3/L/q/w+T0OJfcrWngTs\n" + + "uVcIuvUr32ObPeeWbg/m/lkN7hqH1jY62iybYVrFXiLo1+0G92PUazcyNvyA20+G\n" + + "HsvGG5jlArWNgRLdc8KUXxvnDUxx5vu4jeHEZnqSwuulV1h9ve0UutkmoK0Sk7Rz\n" + + "HMxYK0LmUT5OvcNQSkUi5nLi+M1FxnYYgsELwSiKSSEDfEdgxooMAiVTgw51Q/DB\n" + + "lTOjAIDL3K3J0yGfIG3bwLvE1qz2Z5yWn8f3JibIah7LrC4PiZDDLHFM6V9l+YqU\n" + + "RqimJ5BltSyAx7bxQNZ1AW3Lxvvm894i4k6/Vdf1CDovRuTMPCDAQmKA/A/AQ7TN\n" + + "q3bBimX6UyuJu0I8RyvAYKzFhOOqe4vXrbndTbje/jnzTNQPeIIcuRa9cgXTOrbw\n" + + "86FTUKj6AZXihRWjKWsQpDwdgE0tQETZ3ynCXfbBKfFmn0MSjeX0CEEAZdYHR8EV\n" + + "F271Yt7UJjS/FP702aHTOWk7zFbIRfFQODvBhn0I8p/Stk2sDq4/YsbXVZOe3+ad\n" + + "YavoiODGSAH6ZcZzULumgK9eii0koAOPB/xqXnkcTS63gEHOKjLQl3hqdVZRCugv\n" + + "1CwUXLvoSwIDAQABo4IBYzCCAV8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBTa\n" + + "j6dHgPdOxTGLcwaNDeaMnlSxNjAfBgNVHSMEGDAWgBTaQ0rQ/AHAS79YJ4x2zQqB\n" + + "85Qu9DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYIKwYBBQUHAQEE\n" + + "aTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5zY2EyYS5hbWF6b250cnVzdC5j\n" + + "b20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2NhMmEuYW1hem9udHJ1c3QuY29t\n" + + "L3NjYTJhLmNlcjAlBgNVHREEHjAcghpnb29kLnNjYTJhLmFtYXpvbnRydXN0LmNv\n" + + "bTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYGBWeBDAEBMC0wKwYIKwYBBQUH\n" + + "AgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNvbS9jcHMwDQYJKoZIhvcNAQEM\n" + + "BQADggIBAE6RwZAZvN0i9ygwzqoX9DhSPtvZ3xIO0G0Bhgjkb986+p8XJstU3gEM\n" + + "8P2i1J/YthXCnRGedm+Odxx+31G6xIYfP5S5g7HyRGkj/aXNXy4s3KjH8HJgOY9N\n" + + "ra3XfC05OKq5FpyZQDZ+hxCdLrH3Gs+UxREbu+LuIKUpI7nMVEjn9XynKyOdKN21\n" + + "Kq5VsuI0fDWCYvUN1M+lI/LgE5HbNJVQJs+dB7g1/kaOeaLia7Wk1ys+uRzB58rp\n" + + "FKAoLk++HWTfNDkbN8vKRfHhJ/xhI9ju3TWcci6EyFVAym1C62UkJNI0KHgQ+zc7\n" + + "nl1tv/ytj8N/eJoysyp23lJ5qrVetlQORfgXryGkWBMYBvYF8zbBb/f+UXHDKVWt\n" + + "9l1lL6HQGY/tTo253pj6/FgDD35bZdjLQeUVmbnz679S5oUmoH5ZtSdnpUTghU3p\n" + + "bae9adBFY9S1pm50Q3ckRVBAwNqNmI0KKUh14Ms8KSAUHg19NvGsBonqwOT2rdbv\n" + + "xZ47N6c2eCl/cjMvzre0v0NoUO+3og2GHeAoOwVos6480YDbMqp739tOFPxBcsII\n" + + "6SjpDVh+14dkSW6kEKeaCFLR+eChqutri1VQbQ49nmADQWw9Al8vBytSnPv0YN6W\n" + + "XfIE1Qj7YmHu/UuoeKVsqDqoP/no29+96dtfd4afJqlIoyZUqXpt\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + //Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US + //Serial number: 6f1d782c0aa2f4866b7b522c279b939b92369 + //Valid from: Mon Jan 28 15:37:45 PST 2019 until: Thu Apr 28 16:37:45 PDT 2022 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIG2zCCBMOgAwIBAgITBvHXgsCqL0hmt7Uiwnm5ObkjaTANBgkqhkiG9w0BAQwF\n" + + "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + + "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM3NDVaFw0yMjA0\n" + + "MjgyMzM3NDVaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + + "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" + + "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" + + "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" + + "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTJhLmFtYXpvbnRydXN0LmNvbTCCAiIwDQYJ\n" + + "KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKFm418X8hN1YTgD2XpMb4sp78mw8k3j\n" + + "Dq/vnpX48evVUzNpHpy4qRz/ZHBR4HUJO4lhfnX+CO0uRqqqx4F0JZRQB3KevaU8\n" + + "QGWHdJGhEddnurDhrgOUa+ZroqUnMCsTJfbyGtC6aiEXeu/eMhEUFkuBxJH1JtwD\n" + + "dQXMXuMjG07SVjOkhTkbMDzA/YbUqkDeOIybifDuvA5LEsl+kReY0b6RYFo2Tt/M\n" + + "dPhJD8q3Wsu+XCiCnbpcwlEVGxiD2RVRXJJ9o3ALGOxqU69V+lYS0kkwNHT7oV9J\n" + + "rhgt7iOCq0aoTAxu2j4FCp0JHNhGoW9pXoMXnmS6kK80hzLNYDxvKEaVaKkiYHw5\n" + + "CV0Vwii05ICa14nrStH/jcRNLyU+gp+6OeerPV3jpKWshGKWewF+2UiWU2WHTSrd\n" + + "Wis0/qEfFK/kSraAxpd+KavEEavKeudoMAHIxMACOk9E/fF5zhd2y4G1q1BdoRlR\n" + + "KP4GIV2v6qH6Ru2mNSuge9il6kDXxFNucrYKLDbAqkqalohkvDavcPoG9gZT3etv\n" + + "4IcgJriIWRxbJwKPpwJM+6wa6RpwoeJMuEp3ZBP7KDaQ8YX4rlf4zXLAsOKCNA9K\n" + + "OS/qYQ/I4g0E1WhfgEKClaLPS2u7jeVR6s1t4txGo4vq5Dkt17KTCew/WsX3rckf\n" + + "a2p5zvFcfpCNAgMBAAGjggEpMIIBJTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYE\n" + + "FAF8N1wV8EoYFkMXH6tEnmR/7vI+MB8GA1UdIwQYMBaAFNpDStD8AcBLv1gnjHbN\n" + + "CoHzlC70MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcB\n" + + "AQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTJhLmFtYXpvbnRydXN0\n" + + "LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2EyYS5hbWF6b250cnVzdC5j\n" + + "b20vc2NhMmEuY2VyMCgGA1UdEQQhMB+CHXJldm9rZWQuc2NhMmEuYW1hem9udHJ1\n" + + "c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBDAUAA4ICAQBC\n" + + "VwR1NFk1IYIF4cjU7ML1aj8OIn+8mtakGQnuSJLK6ypSysINJBS48ZDdP6XZXvyD\n" + + "iTS0xEAPjAZHTqrABdNYmvJeL2RnN99DIwVzBpZp4NLTXbiSW7jb0Y5cEPDGJMOo\n" + + "SUAAM6fsiPRfz5vX4XVPznbcF2AwE/NVV+L3n9LVRt7qv2VqIEvLioR56Dq+5ofR\n" + + "4bw0BVlEYWF4Gsy7WDDTL1iLNBUwZTqBHwTv0fgDRiPqb/odmLQuRANwcJy8B8Zr\n" + + "s/yX4SeESaRdA82lAlQilksQitXS2qvQN06GEDOgUxYE6EabFdgklV5JypKqdOly\n" + + "vzpaDpF3z5W8Bj3D4fns1Kjrh1pPh5JRvg+616diKnQRt4X5q+EtmnXhDvIGMISI\n" + + "FuGwj57CNQ2x2MY2HHKWPrOccpQfEEvoSNR+ntYWrtSSttZq948O+zZBk1TXWuXV\n" + + "TVXllqTg8lp6d5cfKgvtHKgt98WkpPOcLVrNuVnMAIfDw6ar54dVKqrvkeEcF6mJ\n" + + "7oMKjJX/Vu9lYoGViBIfdeqcCPWSI8BpnCKaG7dTQO3Q1ObGmLdGBRlsRh+d+S5l\n" + + "Fq326ckbjx537e5/ai31lOR7OwVh9TDweKLqIACjs987C0EJSEfoOue25WRww2va\n" + + "iX9SrTPm4GxQ2OJgYwx0+HbezJXFN+dhaOFUavTSFw==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // EE certificates don't have CRLDP extension + if (!ocspEnabled){ + pathValidator.validate(new String[]{INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + return; + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Jan 28 15:38:57 PST 2019", System.out); + } +} + +class AmazonCA_3 { + + // Owner: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US + // Serial number: 67f945758fe55b9ee3f75831d47f07d226c8a + // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIICuzCCAmGgAwIBAgITBn+UV1j+VbnuP3WDHUfwfSJsijAKBggqhkjOPQQDAjA5\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + + "Um9vdCBDQSAzMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" + + "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDNB\n" + + "MQ8wDQYDVQQDEwZBbWF6b24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATYcYsK\n" + + "mYdR0Gj8Xz45E/lfcTTnXhg2EtAIYBIHyXv/ZQyyyCas1aptX/I5T1coT6XK181g\n" + + "nB8hADuKfWlNoIYRo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n" + + "Af8EBAMCAYYwHQYDVR0OBBYEFATc4JXl6LlrlKHvjFsxHhN+VZfaMB8GA1UdIwQY\n" + + "MBaAFKu229cGnjesMIYHkXDHnMQZsXjAMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEF\n" + + "BQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMy5hbWF6b250cnVzdC5jb20wOgYIKwYB\n" + + "BQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNh\n" + + "My5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EzLmFtYXpv\n" + + "bnRydXN0LmNvbS9yb290Y2EzLmNybDARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZI\n" + + "zj0EAwIDSAAwRQIgOl/vux0qfxNm05W3eofa9lKwz6oKvdu6g6Sc0UlwgRcCIQCS\n" + + "WSQ6F6JHLoeOWLyFFF658eNKEKbkEGMHz34gLX/N3g==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=good.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US + // Serial number: 703e4e9bbc2605f37967a0e95f31f4789a677 + // Valid from: Mon Jul 29 16:54:43 PDT 2019 until: Sat Aug 29 16:54:43 PDT 2020 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDhzCCAy2gAwIBAgITBwPk6bvCYF83lnoOlfMfR4mmdzAKBggqhkjOPQQDAjBG\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + + "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0NDNaFw0yMDA4Mjky\n" + + "MzU0NDNaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + + "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" + + "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" + + "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" + + "MCEGA1UEAxMaZ29vZC5zY2EzYS5hbWF6b250cnVzdC5jb20wWTATBgcqhkjOPQIB\n" + + "BggqhkjOPQMBBwNCAARl4yxf8XcvWR0LZ+YuBC0CpkwtU2NiMdlIM7eX0lxhQp53\n" + + "NpLlCrPRNzOWrjCJDdn21D0u7PrtN94UHLHOg9X0o4IBYzCCAV8wDgYDVR0PAQH/\n" + + "BAQDAgeAMB0GA1UdDgQWBBT2cHmOJFLWfg1Op7xAdAnqYcwaPzAfBgNVHSMEGDAW\n" + + "gBQE3OCV5ei5a5Sh74xbMR4TflWX2jAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + + "BQUHAwIwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5z\n" + + "Y2EzYS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2Nh\n" + + "M2EuYW1hem9udHJ1c3QuY29tL3NjYTNhLmNlcjAlBgNVHREEHjAcghpnb29kLnNj\n" + + "YTNhLmFtYXpvbnRydXN0LmNvbTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYG\n" + + "BWeBDAEBMC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNv\n" + + "bS9jcHMwCgYIKoZIzj0EAwIDSAAwRQIgURdcqJVr4PWNIkmWcSKmzgZ1i94hQpGe\n" + + "mWbE9osk4m0CIQDhxIguihwvDa5RsBwdM0aRDgGKLNHigGqJoKqgH0d2qg==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US + // Serial number: 6f1d78cf0ca64ce7f551a6f2a0715cc0e8b50 + // Valid from: Mon Jan 28 15:40:01 PST 2019 until: Thu Apr 28 16:40:01 PDT 2022 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDTzCCAvWgAwIBAgITBvHXjPDKZM5/VRpvKgcVzA6LUDAKBggqhkjOPQQDAjBG\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + + "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQwMDFaFw0yMjA0Mjgy\n" + + "MzQwMDFaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + + "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" + + "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" + + "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" + + "JAYDVQQDEx1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTBZMBMGByqGSM49\n" + + "AgEGCCqGSM49AwEHA0IABJNl90Jq0wddpFj+JbLtmvGR/1geL5t1tvV406jGpYn2\n" + + "C5lAFjwASFy7pAnazZbfSkIDUU2i2XU0+7Cs+j1S/EOjggEpMIIBJTAOBgNVHQ8B\n" + + "Af8EBAMCB4AwHQYDVR0OBBYEFPhX3dYays5Sps0xTgouLkZzYLg4MB8GA1UdIwQY\n" + + "MBaAFATc4JXl6LlrlKHvjFsxHhN+VZfaMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\n" + + "BgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3Nw\n" + + "LnNjYTNhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5z\n" + + "Y2EzYS5hbWF6b250cnVzdC5jb20vc2NhM2EuY2VyMCgGA1UdEQQhMB+CHXJldm9r\n" + + "ZWQuc2NhM2EuYW1hem9udHJ1c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMAoG\n" + + "CCqGSM49BAMCA0gAMEUCICLb16/50S4fOAFafi5lagdx7q6EDPPm596g19eQDMXk\n" + + "AiEAksCMLypRB4t30FABlsEjhVCBIxay0iIer2OcCIrhfEI=\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // EE certificates don't have CRLDP extension + if (!ocspEnabled){ + pathValidator.validate(new String[]{INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + return; + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Jan 28 15:40:35 PST 2019", System.out); + } +} + +class AmazonCA_4 { + + // Owner: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 4, O=Amazon, C=US + // Serial number: 67f94575a8862a9072e3239c37ceba1274e18 + // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIC+TCCAn6gAwIBAgITBn+UV1qIYqkHLjI5w3zroSdOGDAKBggqhkjOPQQDAzA5\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + + "Um9vdCBDQSA0MB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" + + "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDRB\n" + + "MQ8wDQYDVQQDEwZBbWF6b24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASRP0kIW0Ha\n" + + "7+ORvEVhIS5gIgkH66X5W9vBRTX14oG/1elIyI6LbFZ+E5KAufL0XoWJGI1WbPRm\n" + + "HW246FKSzF0wOEZZyxEROz6tuaVsnXRHRE76roS/Wr064uJpKH+Lv+SjggE5MIIB\n" + + "NTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU\n" + + "pSHN2+tTIZmqytlnQpQlsnv0wuMwHwYDVR0jBBgwFoAU0+zHOmVuzOHadppW+5zz\n" + + "hm1X5YEwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5y\n" + + "b290Y2E0LmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5y\n" + + "b290Y2E0LmFtYXpvbnRydXN0LmNvbS9yb290Y2E0LmNlcjA/BgNVHR8EODA2MDSg\n" + + "MqAwhi5odHRwOi8vY3JsLnJvb3RjYTQuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTQu\n" + + "Y3JsMBEGA1UdIAQKMAgwBgYEVR0gADAKBggqhkjOPQQDAwNpADBmAjEA59RAOBaj\n" + + "uh0rT/OOTWPEv6TBnb9XEadburBaXb8SSrR8il+NdkfS9WXRAzbwrG7LAjEA3ukD\n" + + "1HrQq+WXHBM5sIuViJI/Zh7MOjsc159Q+dn36PBqLRq03AXqE/lRjnv8C5nj\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=good.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US + // Serial number: 703e4ec57c72d5669efbc98875c3f6bc3f934 + // Valid from: Mon Jul 29 16:55:17 PDT 2019 until: Sat Aug 29 16:55:17 PDT 2020 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDxTCCA0qgAwIBAgITBwPk7FfHLVZp77yYh1w/a8P5NDAKBggqhkjOPQQDAzBG\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + + "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU1MTdaFw0yMDA4Mjky\n" + + "MzU1MTdaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + + "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" + + "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" + + "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" + + "MCEGA1UEAxMaZ29vZC5zY2E0YS5hbWF6b250cnVzdC5jb20wdjAQBgcqhkjOPQIB\n" + + "BgUrgQQAIgNiAAS9fqMYfOBsdXMSsPjqOlTgIGOlOQWA7Wg6XwVvHTr0+UN+XTeC\n" + + "yZN+XjLbEDQ0CF5eryRZ535sDpwh3qNe0lYFO1n1+2iDtDI1jhhLNYNxBpVnR2BU\n" + + "2l9EuRmgRbQpDCajggFjMIIBXzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFMd0\n" + + "itH5IcE6DpM1uTSBV/6DLmK7MB8GA1UdIwQYMBaAFKUhzdvrUyGZqsrZZ0KUJbJ7\n" + + "9MLjMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRp\n" + + "MGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTRhLmFtYXpvbnRydXN0LmNv\n" + + "bTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2E0YS5hbWF6b250cnVzdC5jb20v\n" + + "c2NhNGEuY2VyMCUGA1UdEQQeMByCGmdvb2Quc2NhNGEuYW1hem9udHJ1c3QuY29t\n" + + "MFAGA1UdIARJMEcwDQYLYIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcC\n" + + "ARYfaHR0cHM6Ly93d3cuYW1hem9udHJ1c3QuY29tL2NwczAKBggqhkjOPQQDAwNp\n" + + "ADBmAjEA2RBD1F+rnm394VkqA3ncysM3deoyfWqaoAO5923MNisswPnHfVqnfeXf\n" + + "ZwTAvVTBAjEAiiaPx9GRjEk8IBKvCSbTp9rPogVTN7zDDQGrwA83O0pRP7A0dxtT\n" + + "pn/0K5Sj8otp\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ + // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US + // Serial number: 6f1d79295c384a699d51c2d756bd46213b5b3 + // Valid from: Mon Jan 28 15:41:16 PST 2019 until: Thu Apr 28 16:41:16 PDT 2022 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDjTCCAxKgAwIBAgITBvHXkpXDhKaZ1RwtdWvUYhO1szAKBggqhkjOPQQDAzBG\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + + "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQxMTZaFw0yMjA0Mjgy\n" + + "MzQxMTZaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + + "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" + + "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" + + "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" + + "JAYDVQQDEx1yZXZva2VkLnNjYTRhLmFtYXpvbnRydXN0LmNvbTB2MBAGByqGSM49\n" + + "AgEGBSuBBAAiA2IABLuNpZTcNU3FElNP3Y/OeXIZcIMXkFTBi/n92fNwHfqUbEhH\n" + + "H+PovJ26eAGvb5a8bGc275MBFcVnWL0rCVgM+j9KAtBDCRJX3f7mo0D2VKcmtZKu\n" + + "jPxwGPy2kuqM505dGqOCASkwggElMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQU\n" + + "zUFIhn+hphzCKA2qgAdLztSBzJgwHwYDVR0jBBgwFoAUpSHN2+tTIZmqytlnQpQl\n" + + "snv0wuMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEB\n" + + "BGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhNGEuYW1hem9udHJ1c3Qu\n" + + "Y29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTRhLmFtYXpvbnRydXN0LmNv\n" + + "bS9zY2E0YS5jZXIwKAYDVR0RBCEwH4IdcmV2b2tlZC5zY2E0YS5hbWF6b250cnVz\n" + + "dC5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwMDaQAwZgIxALDA\n" + + "klY3iKwyzwpwVtLfLxzQEl45xvE2VjBJvfJJ60KhJt7Ud0gt0zxkogh29+mpEQIx\n" + + "ANTG1mk8OJB41DU7ru1Pwc6ju8STw1FdwDp/Eliqhvnm2i0k4/F1bBHLta2mlC2V\n" + + "hg==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // EE certificates don't have CRLDP extension + if (!ocspEnabled){ + pathValidator.validate(new String[]{INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + return; + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Jan 28 15:41:53 PST 2019", System.out); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 2020-01-15 20:05:09.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8189131 + * @bug 8189131 8231887 * @summary Interoperability tests with Comodo RSA, ECC, userTrust RSA, and * userTrust ECC CAs * @build ValidatePathWithParams @@ -112,13 +112,66 @@ // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, + // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Serial number: a0c7cabcc25ed9358ded02cc1d485545 + // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIH0TCCBrmgAwIBAgIRAKDHyrzCXtk1je0CzB1IVUUwDQYJKoZIhvcNAQELBQAw\n" + + "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + + "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" + + "VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" + + "ciBDQTAeFw0xOTA5MzAwMDAwMDBaFw0yMTEyMjgyMzU5NTlaMIIBPjERMA8GA1UE\n" + + "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" + + "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRAw\n" + + "DgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1UcmFmZm9yZCBSb2FkMRYwFAYDVQQJ\n" + + "Ew1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwzcmQgRmxvb3IsIDI2IE9mZmljZSBW\n" + + "aWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9E\n" + + "TyBFViBTR0MgU1NMMTgwNgYDVQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0\n" + + "aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n" + + "AQoCggEBAND/eZQBTjpBDsuteKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4Of\n" + + "elMhKhN1Od9KU6onHGOd2w4mD4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+\n" + + "8y1zsGVUulpN/GfMaxTb4XdmeSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHv\n" + + "iC9WNrG8CIg/j5MyC9i43LZHiRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q\n" + + "0ZJH+AxL2ERaT41VCppboZwThmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPE\n" + + "ynEU004jFFCEumPUqqCC4ogxulphY80CAwEAAaOCA3EwggNtMB8GA1UdIwQYMBaA\n" + + "FDna/8ooFIqodBMIueQOqdL6fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq\n" + + "89Ux/jAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggr\n" + + "BgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzAp\n" + + "BggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EM\n" + + "AQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09N\n" + + "T0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggr\n" + + "BgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29t\n" + + "L0NPTU9ET1JTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk\n" + + "BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGC\n" + + "L2NvbW9kb3JzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29t\n" + + "MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdQDuS723dc5guuFCaR+r4Z5mow9+\n" + + "X7By2IMAxHuJeqj9ywAAAW2DAXefAAAEAwBGMEQCIDqP1einOiPHnaG1fOZMDrEc\n" + + "RAxjq3vEl94fp4pkmke7AiBsJOvPE6irgcOO1/lnP7NRuln7iPJjU7T20PEK5/rm\n" + + "KwB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYMBd0kAAAQD\n" + + "AEcwRQIhALgUI5XxM1NHbJDdr19h2pe3LhzK4tpuB/OQ9BgCyrGXAiBdr6mNCB/G\n" + + "rbdVx0u7iezwC7mq7iaWugR3rrWlSA8fWQB2ALvZ37wfinG1k5Qjl6qSe0c4V5UK\n" + + "q1LoGpCWZDaOHtGFAAABbYMBd1oAAAQDAEcwRQIgXbG32dagMeLhuZb+LSpJO1vI\n" + + "BmxmRnNdiz5FbG9cCbwCIQCr1X9f+ebT5fhlDUNBURUorTtM8QQciBiueBqvHk7+\n" + + "1DANBgkqhkiG9w0BAQsFAAOCAQEAM/A/1dgoc5NP1n+w3SX9qWcN7QT7ExdrnZSl\n" + + "Ygn0PF2fx4gz7cvNKucbpQJNA4C9awGydyYK8/o5KDUXt3K7eb1OAZ/NZBjygsJs\n" + + "ikXvxlBh8oEoqBOfOtr24l0NGUWnP8Qeu/VPcIMER4V8qX+in0pCXkSd67nkp6Bs\n" + + "EcqhDPgmzdSC1gQHsZuBdotG14OfdH1cG1bRK6GadISLG1h8BFukVem42B149v8F\n" + + "MCIUQAYprAVv2WlTZKBx9XzuK6IK3+klHZ07Jfvjvt7PPG5HKSMWBMnMaTHKcyQI\n" + + "G3t91yw7BnNNInZlBSsFtqjbHhDcr7uruZdbi0rerSsi2qDr0w==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, + // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, // ST=Greater Manchester, C=GB // Serial number: d3df2597cbed1ab6e02ee82021771614 // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIH7jCCBtagAwIBAgIRANPfJZfL7Rq24C7oICF3FhQwDQYJKoZIhvcNAQELBQAw\n" + "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" + @@ -164,60 +217,6 @@ "YrTYerPngjPbZB0bfLOja0vb\n" + "-----END CERTIFICATE-----"; - // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, - // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 720aa2cfa40094521224f901a984b167 - // Valid from: Thu Jun 29 17:00:00 PDT 2017 until: Sun Sep 29 16:59:59 PDT 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIH8jCCBtqgAwIBAgIQcgqiz6QAlFISJPkBqYSxZzANBgkqhkiG9w0BAQsFADCB\n" + - "kjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" + - "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNV\n" + - "BAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" + - "IENBMB4XDTE3MDYzMDAwMDAwMFoXDTE5MDkyOTIzNTk1OVowggFdMREwDwYDVQQF\n" + - "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" + - "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZ\n" + - "BgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQG\n" + - "A1UECRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMG\n" + - "A1UECRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09N\n" + - "T0RPIENBIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9ETyBFViBTR0MgU1NMMTgwNgYD\n" + - "VQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2Nh\n" + - "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAND/eZQBTjpBDsut\n" + - "eKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4OfelMhKhN1Od9KU6onHGOd2w4m\n" + - "D4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+8y1zsGVUulpN/GfMaxTb4Xdm\n" + - "eSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHviC9WNrG8CIg/j5MyC9i43LZH\n" + - "iRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q0ZJH+AxL2ERaT41VCppboZwT\n" + - "hmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPEynEU004jFFCEumPUqqCC4ogx\n" + - "ulphY80CAwEAAaOCA3QwggNwMB8GA1UdIwQYMBaAFDna/8ooFIqodBMIueQOqdL6\n" + - "fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq89Ux/jAOBgNVHQ8BAf8EBAMC\n" + - "BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n" + - "TwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6\n" + - "Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" + - "R4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0ZW5kZWRWYWxp\n" + - "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYB\n" + - "BQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUV4dGVuZGVk\n" + - "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDov\n" + - "L29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGCL2NvbW9kb3JzYWNlcnRpZmlj\n" + - "YXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIBgAYKKwYBBAHWeQIEAgSC\n" + - "AXAEggFsAWoAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVz5\n" + - "cV7GAAAEAwBHMEUCIQCpgc0Eqw3g4pr+oX88h5xgL1VEAiDpqAhbRtilgYwBbgIg\n" + - "UaIm+n8AHi55nB//Sb4Nz18GYVcfELfpIzRh1vW9HbYAdwBWFAaaL9fC7NP14b1E\n" + - "sj7HRna5vJkRXMDvlJhV1onQ3QAAAVz5cVybAAAEAwBIMEYCIQDdsgC4KZ++OP44\n" + - "X7LbUcNaxe0kFzbctF2L3bnmhp9nXQIhAM0/g+PrZBIBpYlOtzidePi8bBHrLWn2\n" + - "uBiP3pYIntl4AHcA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFc\n" + - "+XFeoQAABAMASDBGAiEAoySTb/QKw7JwtZtPHnECEMzgENQSFy58Kl+Mvcd3SmcC\n" + - "IQD8cU66Ih3ejvt0OTX+lfxQPKyggQfm4Uk/lwn5LEJXbDANBgkqhkiG9w0BAQsF\n" + - "AAOCAQEAKEaSYWn3Hi8rfJS4cMTJoMkVp2vpPH2dGXySBEy67TEGRw9+f75w3q95\n" + - "r1m3P+xsR6dBoidTq/6wqUYI51lB4Fq9ylh1Stp5Gj54CuyT+S31l7lD7sl0KMsn\n" + - "HDUDQHId7hKeORYpiIZOcrKOglKdi1uiGwDgoiLKh98lUrZA6durrhH+sl69wqp2\n" + - "0XAu+3hurXzCoZFJfyngTO1kt9qcFUAxc5LofIa9QvC6VR7dI4aAh7dUpIRlnjG3\n" + - "jJ1mUMTqWO6TFTtddb+uQjDqNgkYYYNuSax1WMEIZWbIi13EjXK1GPQUXJe6gQin\n" + - "NUq9JH9NPK6m8A1YKT+wgzfTDeaV2Q==\n" + - "-----END CERTIFICATE-----"; - public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid pathValidator.validate(new String[]{VALID, INT}, @@ -226,7 +225,7 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Thu Nov 29 08:41:09 PST 2018", System.out); + "Wed Oct 02 06:06:24 PDT 2019", System.out); } } @@ -263,13 +262,58 @@ // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited, // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, + // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Serial number: 7972d9d8472a2d52ad1ee6edfb16cbe1 + // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGPzCCBeWgAwIBAgIQeXLZ2EcqLVKtHubt+xbL4TAKBggqhkjOPQQDAjCBkjEL\n" + + "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" + + "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" + + "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + + "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggE6MREwDwYDVQQFEwgw\n" + + "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + + "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" + + "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" + + "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" + + "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEWMBQGA1UECxMNQ09NT0RPIEVW\n" + + "IFNTTDE4MDYGA1UEAxMvY29tb2RvZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1l\n" + + "di5jb21vZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS3bqoFLtNG\n" + + "7/J9H5GKosDNbYL5SykVmU5FzgSEt81gyAWShkqMSfAnO50fpr65E+o86E+BR3o8\n" + + "V9FAU5wuOaGBo4IDcDCCA2wwHwYDVR0jBBgwFoAU007DGbpYWdEcYLdhU0c7p3eP\n" + + "+IowHQYDVR0OBBYEFOlnS3MqxwXDpne8IQMXMZHlVKRXMA4GA1UdDwEB/wQEAwIF\n" + + "gDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBP\n" + + "BgNVHSAESDBGMDsGDCsGAQQBsjEBAgEFATArMCkGCCsGAQUFBwIBFh1odHRwczov\n" + + "L3NlY3VyZS5jb21vZG8uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBH\n" + + "hkVodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FQ0NFeHRlbmRlZFZhbGlk\n" + + "YXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYcGCCsGAQUFBwEBBHsweTBRBggrBgEF\n" + + "BQcwAoZFaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRW\n" + + "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8v\n" + + "b2NzcC5jb21vZG9jYS5jb20wOgYDVR0RBDMwMYIvY29tb2RvZWNjY2VydGlmaWNh\n" + + "dGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF8BgorBgEEAdZ5AgQCBIIB\n" + + "bASCAWgBZgB1AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABbYME\n" + + "EzgAAAQDAEYwRAIgbdo71lBleuJiq+D0ZLp51oVUyWD9EyrtgBSCNwIW4cMCIAqg\n" + + "0VFTWHEmAVjaV23fGj3Ybu3mpSiHr6viGlgA2lYaAHUAVYHUwhaQNgFK6gubVzxT\n" + + "8MDkOHhwJQgXL6OqHQcT0wwAAAFtgwQTKAAABAMARjBEAiBb/gW1RU7kgFBiNpHx\n" + + "LStujKIocyENUTXsMbsac+LktwIgXbEr8vOOCEdBdXQ2F/FKec8ft6gz57mHNmwl\n" + + "pp7phbQAdgC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DBBM6\n" + + "AAAEAwBHMEUCIQDjKN3h86ofR94+JxLFoYuoA+DRtxEY8XGg+NQXlZfUrgIgEoO2\n" + + "ZzKbGfohdwj/WtDwJDRX5pjXF4M0nECiwtYXDIwwCgYIKoZIzj0EAwIDSAAwRQIg\n" + + "AkIRVQBwrElFjrnqk5XPvnlnwkIm1A70ayqOf1FexoQCIQC8tBTn//RCfrhcgTjd\n" + + "ER4wRjFfFoc6lC68OHGVg9CZZg==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited, + // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, // ST=Greater Manchester, C=GB // Serial number: 603a5c2f85b63e00ba46ce8c3f6000b0 // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIGXzCCBgWgAwIBAgIQYDpcL4W2PgC6Rs6MP2AAsDAKBggqhkjOPQQDAjCBkjEL\n" + "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" + "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" + @@ -307,52 +351,6 @@ "KOC7\n" + "-----END CERTIFICATE-----"; - // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=COMODO CA Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, - // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford, - // ST=Greater Manchester, C=GB - // Serial number: 414e5d66ec7d15ca504213f2811d57af - // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGYDCCBgWgAwIBAgIQQU5dZux9FcpQQhPygR1XrzAKBggqhkjOPQQDAjCBkjEL\n" + - "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" + - "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" + - "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + - "MB4XDTE3MDcwNDAwMDAwMFoXDTE5MTAwMzIzNTk1OVowggFZMREwDwYDVQQFEwgw\n" + - "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + - "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZBgNV\n" + - "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQGA1UE\n" + - "CRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMGA1UE\n" + - "CRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09NT0RP\n" + - "IENBIExpbWl0ZWQxFjAUBgNVBAsTDUNPTU9ETyBFViBTU0wxODA2BgNVBAMTL2Nv\n" + - "bW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMFkw\n" + - "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt26qBS7TRu/yfR+RiqLAzW2C+UspFZlO\n" + - "Rc4EhLfNYMgFkoZKjEnwJzudH6a+uRPqPOhPgUd6PFfRQFOcLjmhgaOCA3EwggNt\n" + - "MB8GA1UdIwQYMBaAFNNOwxm6WFnRHGC3YVNHO6d3j/iKMB0GA1UdDgQWBBTpZ0tz\n" + - "KscFw6Z3vCEDFzGR5VSkVzAOBgNVHQ8BAf8EBAMCBYAwDAYDVR0TAQH/BAIwADAd\n" + - "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEE\n" + - "AbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNv\n" + - "bS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21v\n" + - "ZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVy\n" + - "Q0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQu\n" + - "Y29tb2RvY2EuY29tL0NPTU9ET0VDQ0V4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNl\n" + - "cnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29t\n" + - "MDoGA1UdEQQzMDGCL2NvbW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYu\n" + - "Y29tb2RvY2EuY29tMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgCkuQmQtBhY\n" + - "FIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAV0NLqsqAAAEAwBHMEUCIAz9Jjq3\n" + - "qLUd/a2PYZnLGsEG/MrL7vab5rmGBg8RGAJxAiEA7JJnar07NIjCLLO77xJ3UFcu\n" + - "UMM3M8JgGC8wbuRwxbUAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ\n" + - "3QAAAV0NLqjmAAAEAwBHMEUCIHRvPWKr7vPMBWx1gLPkt8inPINWPNSoax178e5A\n" + - "D0cPAiEAvRL/VP4DLiyHvcU9AOqTzQXGuWCzswWKG59hSm7gS4kAdQDuS723dc5g\n" + - "uuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAV0NLqsDAAAEAwBGMEQCIFALT043\n" + - "X5IffLsxIAGXTrWgkZHf12QKgrYKXVB629eOAiAIeci2xi3fUW6mU8tT4LwyjowV\n" + - "DkrSCw1ZMo0JApsfzTAKBggqhkjOPQQDAgNJADBGAiEA7HUxjwx0MBC+4PuPx4Z1\n" + - "WpKz7jdHOMTh1sdaoVV5hNoCIQDrnjBFUopXHTvm/rj+aMFIeYejggPqv14KJOqT\n" + - "gym+uA==\n" + - "-----END CERTIFICATE-----"; - public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid pathValidator.validate(new String[]{VALID, INT}, @@ -361,19 +359,61 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Thu Nov 29 08:12:02 PST 2018", System.out); + "Wed Oct 02 06:05:57 PDT 2019", System.out); } } class ComodoUserTrustRSA { + // Owner: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US + // Serial number: 284e39c14b386d889c7299e58cd05a57 + // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGNDCCBBygAwIBAgIQKE45wUs4bYiccpnljNBaVzANBgkqhkiG9w0BAQwFADCB\n" + + "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" + + "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" + + "BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx\n" + + "MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBkTELMAkGA1UEBhMCR0IxGzAZBgNV\n" + + "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE\n" + + "ChMPU2VjdGlnbyBMaW1pdGVkMTkwNwYDVQQDEzBTZWN0aWdvIFJTQSBFeHRlbmRl\n" + + "ZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUA\n" + + "A4IBDwAwggEKAoIBAQCaoslYBiqFev0Yc4TXPa0s9oliMcn9VaENfTUK4GVT7niB\n" + + "QXxC6Mt8kTtvyr5lU92hDQDh2WDPQsZ7oibh75t2kowT3z1S+Sy1GsUDM4NbdOde\n" + + "orcmzFm/b4bwD4G/G+pB4EX1HSfjN9eT0Hje+AGvCrd2MmnxJ+Yymv9BH9OB65jK\n" + + "rUO9Na4iHr48XWBDFvzsPCJ11Uioof6dRBVp+Lauj88Z7k2X8d606HeXn43h6acp\n" + + "LLURWyqXM0CrzedVWBzuXKuBEaqD6w/1VpLJvSU+wl3ScvXSLFp82DSRJVJONXWl\n" + + "dp9gjJioPGRByeZw11k3galbbF5gFK9xSnbDx29LAgMBAAGjggGNMIIBiTAfBgNV\n" + + "HSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQULGn/gMmHkK40\n" + + "4bTnTJOFmUDpp7IwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" + + "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDoGA1UdIAQzMDEwLwYEVR0g\n" + + "ADAnMCUGCCsGAQUFBwIBFhlodHRwczovL2Nwcy51c2VydHJ1c3QuY29tMFAGA1Ud\n" + + "HwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RS\n" + + "U0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYI\n" + + "KwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FB\n" + + "ZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0\n" + + "LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAQ4AzPxVypLyy3IjUUmVl7FaxrHsXQq2z\n" + + "Zt2gKnHQShuA+5xpRPNndjvhHk4D08PZXUe6Im7E5knqxtyl5aYdldb+HI/7f+zd\n" + + "W/1ub2N4Vq4ZYUjcZ1ECOFK7Z2zoNicDmU+Fe/TreXPuPsDicTG/tMcWEVM558OQ\n" + + "TJkB2LK3ZhGukWM/RTMRcRdXaXOX8Lh0ylzRO1O0ObXytvOFpkkkD92HGsfS06i7\n" + + "NLDPJEeZXqzHE5Tqj7VSAj+2luwfaXaPLD8lQEVci8xmsPGOn0mXE1ZzsChEPhVq\n" + + "FYQUsbiRJRhidKauhd+G2CkRTcR5fpsuz+iStB9s5Fks9lKoXnn0hv78VYjvR78C\n" + + "Cvj5FW/ounHjWTWMb3il9S5ngbFGcelB1l/MQkR63+1ybdi2OpjNWJCftxOWUpkC\n" + + "xaRdnOnSj7GQY0NLn8Gtq9FcSZydtkVgXpouSFZkXNS/MYwbcCCcRKBbrk8ss0SI\n" + + "Xg1gTURjh9VP1OHm0OktYcUw9e90wHIDn7h0qA+bWOsZquSRzT4s2crF3ZSA3tuV\n" + + "/UJ33mjdVO8wBD8aI5y10QreSPJvZHHNDyCmoyjXvNhR+u3arXUoHWxO+MZBeXbi\n" + + "iF7Nwn/IEmQvWBW8l6D26CXIavcY1kAJcfyzHkrPbLo+fAOa/KFl3lIU+0biEVNk\n" + + "Q9zXE6hC6X4=\n" + + "-----END CERTIFICATE-----"; + // Owner: CN=USERTrust RSA Extended Validation Secure Server CA, // O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, // L=Jersey City, ST=New Jersey, C=US // Serial number: f6bb751efa7d2e8368e606407334f83 // Valid from: Sat Feb 11 16:00:00 PST 2012 until: Thu Feb 11 15:59:59 PST 2027 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIGGTCCBAGgAwIBAgIQD2u3Ue+n0ug2jmBkBzNPgzANBgkqhkiG9w0BAQwFADCB\n" + "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" + "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" @@ -409,15 +449,69 @@ + "4fokbdNREXoShKClNIPbB5iY+WdSzb9CKLyb96g=\n" + "-----END CERTIFICATE-----"; - // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, - // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, - // L=Salford, ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, + // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, + // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester, + // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Serial number: b07fd164b5790c9d5d1fddff5819cdb2 + // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIH5TCCBs2gAwIBAgIRALB/0WS1eQydXR/d/1gZzbIwDQYJKoZIhvcNAQELBQAw\n" + + "gZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" + + "BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UE\n" + + "AxMwU2VjdGlnbyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" + + "IENBMB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFWMREwDwYDVQQF\n" + + "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" + + "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEzAR\n" + + "BgNVBAgTCk1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRy\n" + + "YWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNy\n" + + "ZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGDAWBgNVBAoTD1NlY3RpZ28gTGlt\n" + + "aXRlZDEaMBgGA1UECxMRQ09NT0RPIEVWIFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0\n" + + "cnVzdHJzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIB\n" + + "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh/rxeiYwpLa651eLvGnR+RE\n" + + "rhDWkTZtqZcHw9Oy7JL2uELyEPbM+v0az40cBHS0bQZJZbWmXNukMUMSwIb4z7t8\n" + + "OXlxz9uvxEufvlqBl4qeC/z3LpFBRRHEero3yGKVwkoe1aP2Pq7Udi+7i7eVZZdA\n" + + "1ticxZWo/UBU9mwbIOYqf/4xzZ6G891hKb+NAuuEfxG52vXZl8odMThfHuDlkfS7\n" + + "nZMQBaO40KJeSEBhr+5TIS7d7tWWye/F6oEQ0+dHBiF9PyZ1dXoO8aue/80mP+0F\n" + + "MYTmRFsKHge6ZjojfH9cLlR5kTqtP5Tqh5GBQ4zp3uyIBBU6ylKp9PNHkewGUQID\n" + + "AQABo4IDbjCCA2owHwYDVR0jBBgwFoAULGn/gMmHkK404bTnTJOFmUDpp7IwHQYD\n" + + "VR0OBBYEFHz7cvDn1LYe2M+z4plwQn7rt938MA4GA1UdDwEB/wQEAwIFoDAMBgNV\n" + + "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAE\n" + + "QjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp\n" + + "Z28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js\n" + + "LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FFeHRlbmRlZFZhbGlkYXRpb25TZWN1cmVT\n" + + "ZXJ2ZXJDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBRBggrBgEFBQcwAoZFaHR0cDov\n" + + "L2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2Vj\n" + + "dXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + + "LmNvbTA9BgNVHREENjA0gjJ1c2VydHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9y\n" + + "aXR5LWV2LmNvbW9kb2NhLmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA\n" + + "7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFtgzv54wAABAMARzBF\n" + + "AiB5PmhsK3zU3XdKvyxw/wWHMmLI7apHLa1yKdjkA8H+ggIhALdUx7Tl8aeWhK6z\n" + + "lh+PHvMAdCcAJK6w9qBJGQtSrYO5AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgX\n" + + "L6OqHQcT0wwAAAFtgzv5zgAABAMARjBEAiBumSwAUamibqJXTN2cf/H3mjd0T35/\n" + + "UK9w2hu9gFobxgIgSXTLndHyqFUmcmquu3It0WC1yl6YMceGixbQL1e8BQcAdwC7\n" + + "2d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DO/nXAAAEAwBIMEYC\n" + + "IQDHRs10oYoXE5yq6WsiksjdQsUWZNpbSsrmz0u+KlxTVQIhAJ4rvHItKSeJLkaN\n" + + "S3YpVZnkN8tOwuxPsYeyVx/BtaNpMA0GCSqGSIb3DQEBCwUAA4IBAQAPFIsUFymo\n" + + "VTp0vntHrZpBApBQzDeriQv7Bi7tmou/Ng47RtXW3DjGdrePGSfOdl7h62k8qprU\n" + + "JeLyloDqhvmT/CG/hdwrfZ3Sv3N2xpetGcnW5S3oEi3m+/M1ls9eD+x1vybqV9Kd\n" + + "lcjuV7SYDlbvAS9w7TcygudhdW0cI8XTCvesGKohBkAlqaQ/MWYpt4WvsxHjbWgn\n" + + "5ZlIYR6A1ZFEjADifViH/5AA79lgGhAskkIWPjvRFalEVKTKtjhRK76eCfZs4Frr\n" + + "CEOpon+BeNKk+x/K/r10dSoWe0SV2uGVxTD83zkP++eREwo1hTgn8bXn7ftlnA3j\n" + + "7ml+Usz6udaD\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, + // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, + // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City, // ST=New Jersey, C=US // Serial number: d3c204e8df6a1539568cf15e97e57b1d // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIIADCCBuigAwIBAgIRANPCBOjfahU5VozxXpflex0wDQYJKoZIhvcNAQELBQAw\n" + "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" + "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" + @@ -463,81 +557,56 @@ "3Ld31zbQaywKdpCsT74/hEBMfcDiP02mmtyrlqHD4R3tdYne\n" + "-----END CERTIFICATE-----"; - // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, - // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City, - // ST=New Jersey, C=US - // Serial number: ffcada019c9fb1155a32300083cb99c9 - // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIIATCCBumgAwIBAgIRAP/K2gGcn7EVWjIwAIPLmckwDQYJKoZIhvcNAQELBQAw\n" + - "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" + - "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" + - "VQQDEzJVU0VSVHJ1c3QgUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNl\n" + - "cnZlciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8G\n" + - "A1UEBRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFBy\n" + - "aXZhdGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VR\n" + - "MRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQx\n" + - "FjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkx\n" + - "JTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoT\n" + - "EUNPTU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7\n" + - "MDkGA1UEAxMydXNlcnRydXN0cnNhY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5j\n" + - "b21vZG9jYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCeH+vF\n" + - "6JjCktrrnV4u8adH5ESuENaRNm2plwfD07Lskva4QvIQ9sz6/RrPjRwEdLRtBkll\n" + - "taZc26QxQxLAhvjPu3w5eXHP26/ES5++WoGXip4L/PcukUFFEcR6ujfIYpXCSh7V\n" + - "o/Y+rtR2L7uLt5Vll0DW2JzFlaj9QFT2bBsg5ip//jHNnobz3WEpv40C64R/Ebna\n" + - "9dmXyh0xOF8e4OWR9LudkxAFo7jQol5IQGGv7lMhLt3u1ZbJ78XqgRDT50cGIX0/\n" + - "JnV1eg7xq57/zSY/7QUxhOZEWwoeB7pmOiN8f1wuVHmROq0/lOqHkYFDjOne7IgE\n" + - "FTrKUqn080eR7AZRAgMBAAGjggN8MIIDeDAfBgNVHSMEGDAWgBQvgU/iZvq8aL+Z\n" + - "Q4RSiSA6gvOkpTAdBgNVHQ4EFgQUfPty8OfUth7Yz7PimXBCfuu33fwwDgYDVR0P\n" + - "AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n" + - "AQUFBwMCMEsGA1UdIAREMEIwNwYMKwYBBAGyMQECAQUBMCcwJQYIKwYBBQUHAgEW\n" + - "GWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wBwYFZ4EMAQEwWgYDVR0fBFMwUTBP\n" + - "oE2gS4ZJaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJTQUV4dGVu\n" + - "ZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCBjQYIKwYBBQUHAQEEgYAw\n" + - "fjBVBggrBgEFBQcwAoZJaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVz\n" + - "dFJTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAlBggrBgEF\n" + - "BQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTA9BgNVHREENjA0gjJ1c2Vy\n" + - "dHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCC\n" + - "AX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5\n" + - "G9+443fNDsgN3BAAAAFdDU2iYQAABAMARzBFAiB0o4GnVHD8MeVQ32D0XYu+EQQW\n" + - "jvN78rmCfk0OEBxyFAIhAKgyctIn0IaDJiZzsrtAiqEnkcMtuh8o+R0Rqw1ygAjk\n" + - "AHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDU2gFgAABAMA\n" + - "SDBGAiEA7mcmZ8H5uHuNCdI0CVxsqDZQcZX/gVk94KckePkzQoACIQCHwm5hcvNC\n" + - "M8vNmFkboQN79DglRctHrlh143A6mUTk8QB2AO5Lvbd1zmC64UJpH6vhnmajD35f\n" + - "sHLYgwDEe4l6qP3LAAABXQ1NojoAAAQDAEcwRQIhAPqwijgE0Fr6uJ+yF+TvyXco\n" + - "Hduv9h7R5WWwJfghXiMyAiBB4+fJm4rIcOnJBZmOqFnRpIjPN0jwDqJT0nDHxaXA\n" + - "nDANBgkqhkiG9w0BAQsFAAOCAQEACXitF1bTEvV1HX11WrT/XuoMhsoPK4TS16rs\n" + - "FqztV4iXKlA1/h5qbsjYY1gVrM+/6kQkmEs5qrxsek2WNxY80NO3WAzroRJ3H9Sd\n" + - "mPn0No2P8LZ5Fs5hvaD/PfWO5xxey80c3kGyvWOej90P3IrL/1RiULyh95TrXBjI\n" + - "ddCBsZ28904wsQUrPBPMpiu0DKl1HR/em9WkcipMi+onJxxFWjucssz5PW/BzGYF\n" + - "jfWLDEI0tN5L4CWV3iVXFXOURY1Mwhtsey9jvlEyxSsys55QdKF40yGgtV9VC+os\n" + - "7hJP33+qA0cvCTaRytiPP6z/l2G/KSIXTyv6SxzGhsTFfzLAOg==\n" + - "-----END CERTIFICATE-----"; - public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid - pathValidator.validate(new String[]{VALID, INT}, + pathValidator.validate(new String[]{VALID, INT_VALID}, ValidatePathWithParams.Status.GOOD, null, System.out); // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, ValidatePathWithParams.Status.REVOKED, - "Thu Nov 29 10:58:13 PST 2018", System.out); + "Wed Oct 02 06:07:12 PDT 2019", System.out); } } class ComodoUserTrustECC { + // Owner: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US + // Serial number: 80f5606d3a162b143adc12fbe8c2066f + // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDyTCCA0+gAwIBAgIRAID1YG06FisUOtwS++jCBm8wCgYIKoZIzj0EAwMwgYgx\n" + + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" + + "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQD\n" + + "EyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEw\n" + + "MjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgZExCzAJBgNVBAYTAkdCMRswGQYDVQQI\n" + + "ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT\n" + + "D1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMwU2VjdGlnbyBFQ0MgRXh0ZW5kZWQg\n" + + "VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + + "AQcDQgAEAyJ5Ca9JyXq8bO+krLVWysbtm7fdMSJ54uFD23t0x6JAC4IjxevfQJzW\n" + + "z4T6yY+FybTBqtOa++ijJFnkB5wKy6OCAY0wggGJMB8GA1UdIwQYMBaAFDrhCYbU\n" + + "zxnClnZ0SXbc4DXGY2OaMB0GA1UdDgQWBBTvwSqVDDLa+3Mw3IoT2BVL9xPo+DAO\n" + + "BgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggr\n" + + "BgEFBQcDAQYIKwYBBQUHAwIwOgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUH\n" + + "AgEWGWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wUAYDVR0fBEkwRzBFoEOgQYY/\n" + + "aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0NlcnRpZmljYXRp\n" + + "b25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0\n" + + "cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0FkZFRydXN0Q0EuY3J0\n" + + "MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMAoGCCqGSM49\n" + + "BAMDA2gAMGUCMQCjHztBDL90GCRXHlGqm0H7kzP04hd0MxwakKjWzOmstXNFLONj\n" + + "RFa0JqI/iKUJMFcCMCbLgyzcFW7DihtY5XE0XCLCw+git0NjxiFB6FaOFIlyDdqT\n" + + "j+Th+DJ92JLvICVD/g==\n" + + "-----END CERTIFICATE-----"; + // Owner: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, // L=Jersey City, ST=New Jersey, C=US // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, // L=Jersey City, ST=New Jersey, C=US // Serial number: 3d09b24f5c08a7ce8eb85a51d3c1aa52 // Valid from: Sun Apr 14 17:00:00 PDT 2013 until: Fri Apr 14 16:59:59 PDT 2028 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIDwTCCA0igAwIBAgIQPQmyT1wIp86OuFpR08GqUjAKBggqhkjOPQQDAzCBiDEL\n" + "MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\n" + "eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\n" @@ -563,13 +632,58 @@ // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, + // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford, + // ST=Greater Manchester, C=GB + // Serial number: 8b72489b7f505a55e2a22659c90ed2ab + // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGRTCCBeugAwIBAgIRAItySJt/UFpV4qImWckO0qswCgYIKoZIzj0EAwIwgZEx\n" + + "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" + + "BAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMw\n" + + "U2VjdGlnbyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" + + "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFBMREwDwYDVQQFEwgw\n" + + "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" + + "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" + + "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" + + "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" + + "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEaMBgGA1UECxMRQ09NT0RPIEVW\n" + + "IFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0cnVzdGVjY2NlcnRpZmljYXRpb25hdXRo\n" + + "b3JpdHktZXYuY29tb2RvY2EuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n" + + "LTJfEd92Wlg+h/AVtPsMmwX9Puvi+WGCv3sgFRpur8Iy2kGVpXHRQTCn2j9aky4t\n" + + "FQGm7OG2klJA/MEeevKVaaOCA28wggNrMB8GA1UdIwQYMBaAFO/BKpUMMtr7czDc\n" + + "ihPYFUv3E+j4MB0GA1UdDgQWBBSzrWHzmiHwx2Rrm7SjRC0UegNrKzAOBgNVHQ8B\n" + + "Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + + "BQUHAwIwSQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEFBQcCARYX\n" + + "aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" + + "R4ZFaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDRXh0ZW5kZWRWYWxp\n" + + "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGGBggrBgEFBQcBAQR6MHgwUQYIKwYB\n" + + "BQUHMAKGRWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb0VDQ0V4dGVuZGVk\n" + + "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov\n" + + "L29jc3Auc2VjdGlnby5jb20wPQYDVR0RBDYwNIIydXNlcnRydXN0ZWNjY2VydGlm\n" + + "aWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF/BgorBgEEAdZ5AgQC\n" + + "BIIBbwSCAWsBaQB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAAB\n" + + "bYL/SJoAAAQDAEcwRQIhAL7EJt/Rgz6NBnx2v8Hevux3Gpcxy64kaeyLVgFeNqFk\n" + + "AiBRf+OWLOtZzEav/oERljrk8hgZB4CR1nj/Tn98cmRrwwB2AFWB1MIWkDYBSuoL\n" + + "m1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYL/SIgAAAQDAEcwRQIgVtZZaiBMC2lu\n" + + "atBzUHQmOq4qrUQP7nS83cd3VzPhToECIQDnlpOCdaxJwr8C0MtkvYpKSabwBPFL\n" + + "ASEkwmOpjuQErAB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAAB\n" + + "bYL/SJoAAAQDAEgwRgIhAI8OgzP/kzF1bOJRHU2S/ewij/6HpGPy7Mbm7Hyuv3IU\n" + + "AiEAxDmX2FmORlgeerQmQ+ar3D9/TwA9RQckVDu5IrgweREwCgYIKoZIzj0EAwID\n" + + "SAAwRQIhAPwQWGWd3oR7YJ7ngCDQ9TAbdPgND51SiR34WfEgaTQtAiAxD4umKm02\n" + + "59GEMj5NpyF2ZQEq5mEGcjJNojrn+PC4zg==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited, + // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City, // ST=New Jersey, C=US // Serial number: ab1455f9833ae7783f95de8744181f6a // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + "MIIGhjCCBiygAwIBAgIRAKsUVfmDOud4P5Xeh0QYH2owCgYIKoZIzj0EAwIwgZUx\n" + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" + "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" + @@ -607,60 +721,14 @@ "11EPtBSCEhUCIBcyI0yl5dRff6+4x8IeCrLiAOYsfzM7Y/a5uRKFnbYz\n" + "-----END CERTIFICATE-----"; - // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited, - // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, - // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, - // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690 - // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City, - // ST=New Jersey, C=US - // Serial number: 9bd0c93cac9ca2edc1a7dd923316b3c6 - // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGhzCCBi2gAwIBAgIRAJvQyTysnKLtwafdkjMWs8YwCgYIKoZIzj0EAwIwgZUx\n" + - "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" + - "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" + - "EzJVU0VSVHJ1c3QgRUNDIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" + - "ciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8GA1UE\n" + - "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" + - "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRsw\n" + - "GQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAU\n" + - "BgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAj\n" + - "BgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoTEUNP\n" + - "TU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7MDkG\n" + - "A1UEAxMydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21v\n" + - "ZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtMl8R33ZaWD6H8BW0\n" + - "+wybBf0+6+L5YYK/eyAVGm6vwjLaQZWlcdFBMKfaP1qTLi0VAabs4baSUkD8wR56\n" + - "8pVpo4IDjjCCA4owHwYDVR0jBBgwFoAUKpxa+U6hMNpASyvpS/H1nNwC+S4wHQYD\n" + - "VR0OBBYEFLOtYfOaIfDHZGubtKNELRR6A2srMA4GA1UdDwEB/wQEAwIFgDAMBgNV\n" + - "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBQBgNVHSAE\n" + - "STBHMDwGDCsGAQQBsjEBAgEFATAsMCoGCCsGAQUFBwIBFh5odHRwczovL2Nwcy50\n" + - "cnVzdC1wcm92aWRlci5jb20wBwYFZ4EMAQEwXwYDVR0fBFgwVjBUoFKgUIZOaHR0\n" + - "cDovL2NybC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRydXN0RUNDRXh0ZW5kZWRW\n" + - "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGYBggrBgEFBQcBAQSBizCBiDBa\n" + - "BggrBgEFBQcwAoZOaHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRy\n" + - "dXN0RUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCoGCCsG\n" + - "AQUFBzABhh5odHRwOi8vb2NzcC50cnVzdC1wcm92aWRlci5jb20wPQYDVR0RBDYw\n" + - "NIIydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9j\n" + - "YS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1AKS5CZC0GFgUh7sTosxn\n" + - "cAo8NZgE+RvfuON3zQ7IDdwQAAABXQ0/jQ0AAAQDAEYwRAIgPbaNWgoi6OfyNwL2\n" + - "+jiySsoLrkx+0d4NJE1WnZQcfzwCICW4yvsXaMxoOXpQp3EPgrYk5Ajfvy/dY3Ui\n" + - "0/dbQtHxAHYAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDT+K\n" + - "xwAABAMARzBFAiB3GQasrX+akoHX02ZvXCcvhWCqv6qQOhLCUqflPoRbuAIhALwe\n" + - "hrQo8S1Tm5vbMcxGiViq5ZcawxENWhxZ9hS0BZweAHUA7ku9t3XOYLrhQmkfq+Ge\n" + - "ZqMPfl+wctiDAMR7iXqo/csAAAFdDT+M4AAABAMARjBEAiAjvp8w/fdTVW1VGE0T\n" + - "I0YcCIXTYFDgzUMsEUiKHANAgwIgETQUcac7Hiis2fgQ+GdGF9yuh+xMo2Z8QXNu\n" + - "1Cknf+8wCgYIKoZIzj0EAwIDSAAwRQIgQ5UiUI7xodmmMYNs3CmqlZHw/04BQRAR\n" + - "4gRm7blZSIMCIQDHvIWTaPzSO6vwVzs6wSD6FqebLiFxoddC6aZG8Nm0wQ==\n" + - "-----END CERTIFICATE-----"; - public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid - pathValidator.validate(new String[]{VALID, INT}, + pathValidator.validate(new String[]{VALID, INT_VALID}, ValidatePathWithParams.Status.GOOD, null, System.out); // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, ValidatePathWithParams.Status.REVOKED, - "Thu Nov 29 10:06:00 PST 2018", System.out); + "Wed Oct 02 06:06:50 PDT 2019", System.out); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8232019 + * @summary Interoperability tests with LuxTrust Global Root 2 CA + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath LuxTrustCA OCSP + * @run main/othervm -Djava.security.debug=certpath LuxTrustCA CRL + */ + +/* + * Obtain TLS test artifacts for LuxTrust CAs from: + * + * LuxTrust Global Root 2 CA sent test certificates as attachment + */ +public class LuxTrustCA { + + // Owner: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU + // Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU + // Serial number: 413dea1a28c2253845558e047f3e2a8b5b9baeae + // Valid from: Fri Mar 06 06:12:15 PST 2015 until: Mon Mar 05 05:21:57 PST 2035 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGcjCCBFqgAwIBAgIUQT3qGijCJThFVY4Efz4qi1ubrq4wDQYJKoZIhvcNAQEL\n" + + "BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV\n" + + "BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA2MTQxMjE1WhcNMzUw\n" + + "MzA1MTMyMTU3WjBOMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B\n" + + "LjEnMCUGA1UEAwweTHV4VHJ1c3QgR2xvYmFsIFF1YWxpZmllZCBDQSAzMIICIjAN\n" + + "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuZ5iXSmFbP80gWb0kieYsImcyIo3\n" + + "QYg+XA3NlwH6QtI0PgZEG9dSo8pM7VMIzE5zq8tgJ50HnPdYflvfhkEKvAW2NuNX\n" + + "6hi/6HK4Nye+kB+INjpfAHmLft3GT95e+frk/t7hJNorK44xzqfWZKLNGysEHIri\n" + + "ddcePWOk3J/VMc9CsSemeZbmeZW1/xXeqolMS7JIDZ3+0DgVCYsKIK+b3sAQ8iqX\n" + + "bQlQyvymG6QyoQoJbuEP23iawRMWKNWk+sjzOkPAAQDtgEEVdggzzudLSM04C5Cj\n" + + "eLlLYuXgljler9bKRk9wW8nkareLZsn9uCDihGXGyC5m9jseGY1KAnlV8usLjBFA\n" + + "iW5OCnzcOg+CPsVucoRhS6uvXcu7VtHRGo5yLysJVv7sj6cx5lMvQKAMLviVi3kp\n" + + "hZKYfqVLAVFJpXTpunY2GayVGf/uOpzNoiSRpcxxYjmAlPKNeTgXVl5Mc0zojgT/\n" + + "MZTGFN7ov7n01yodN6OhfTADacvaKfj2C2CwdCJvMqvlUuCKrvuXbdZrtRm3BZXr\n" + + "ghGhuQmG0Tir7VVCI0WZjVjyHs2rpUcCQ6+D1WymKhzp0mrXdaFzYRce7FrEk69J\n" + + "WzWVp/9/GKnnb0//camavEaI4V64MVxYAir5AL/j7d4JIOqhPPU14ajxmC6dEH84\n" + + "guVs0Lo/dwVTUzsCAwEAAaOCAU4wggFKMBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYD\n" + + "VR0gBDwwOjA4BggrgSsBAQEKAzAsMCoGCCsGAQUFBwIBFh5odHRwczovL3JlcG9z\n" + + "aXRvcnkubHV4dHJ1c3QubHUwagYIKwYBBQUHAQEEXjBcMCsGCCsGAQUFBzABhh9o\n" + + "dHRwOi8vbHRncm9vdC5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFodHRw\n" + + "Oi8vY2EubHV4dHJ1c3QubHUvTFRHUkNBMi5jcnQwDgYDVR0PAQH/BAQDAgEGMB8G\n" + + "A1UdIwQYMBaAFP8YKHb5SAUsoa7xKxsrslP4S3yzMDMGA1UdHwQsMCowKKAmoCSG\n" + + "Imh0dHA6Ly9jcmwubHV4dHJ1c3QubHUvTFRHUkNBMi5jcmwwHQYDVR0OBBYEFGOP\n" + + "wosDsauO2FNHlh2ZqH32rKh1MA0GCSqGSIb3DQEBCwUAA4ICAQADB6M/edbOO9iJ\n" + + "COnVxayJ1NBk08/BVKlHwe7HBYAzT6Kmo3TbMUwOpcGI2e/NBCR3F4wTzXOVvFmv\n" + + "dBl7sdS6uMSLBTrav+5LChcFDBQj26X5VQDcXkA8b/u6J4Ve7CwoSesYg9H0fsJ3\n" + + "v12QrmGUUao9gbamKP1TFriO+XiIaDLYectruusRktIke9qy8MCpNSarZqr3oD3c\n" + + "/+N5D3lDlGpaz1IL8TpbubFEQHPCr6JiwR+qSqGRfxv8vIvOOAVxe7np5QhtwmCk\n" + + "XdMOPQ/XOOuEA06bez+zHkASX64at7dXru+4JUEbpijjMA+1jbFZr20OeBIQZL7o\n" + + "Est+FF8lFuvmucC9TS9QnlF28WJExvpIknjS7LhFMGXB9w380q38ZOuKjPZpoztY\n" + + "eyUpf8gxzV7fE5Q1okhnsDZ+12vBzBruzJcwtNuXyLyIh3fVN0LunVd+NP2kGjB2\n" + + "t9WD2Y0CaKxWx8snDdrSbAi46TpNoe04eroWgZOvdN0hEmf2d8tYBSJ/XZekU9sC\n" + + "Aww5vxHnXJi6CZHhjt8f1mMhyE2gBvmpk4CFetViO2sG0n/nsxCQNpnclsax/eJu\n" + + "XmGiZ3OPCIRijI5gy3pLRgnbgLyktWoOkmT/gxtWDLfVZwEt52JL8d550KIgttyR\n" + + "qX81LJWGSDdpnzeRVQEnzAt6+RebAQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: T=Private Person, SERIALNUMBER=00100978855105608536, + // GIVENNAME=TokenPRIActive, SURNAME=Test, CN=TokenPRIActive Test, C=DE + // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU + // Serial number: 3814b6 + // Valid from: Wed Jul 10 04:36:12 PDT 2019 until: Sun Jul 10 04:36:12 PDT 2022 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIG/jCCBOagAwIBAgIDOBS2MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" + + "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" + + "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjEyWhcNMjIwNzEwMTEzNjEy\n" + + "WjCBizELMAkGA1UEBhMCREUxHDAaBgNVBAMTE1Rva2VuUFJJQWN0aXZlIFRlc3Qx\n" + + "DTALBgNVBAQTBFRlc3QxFzAVBgNVBCoTDlRva2VuUFJJQWN0aXZlMR0wGwYDVQQF\n" + + "ExQwMDEwMDk3ODg1NTEwNTYwODUzNjEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24w\n" + + "ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDb8l2RJNS7iA9hJFj8aR25\n" + + "kpU/ZQTHl8Z9yrTLhr4VcMWMxqeOQUcUU27SgIuFvU9s/68OuaIhxyu6eohaGCLC\n" + + "wzFFRg8OlsUYuI1QtUEliIjmHOMDqSNIt093+SDV64osnHw5fpfy8V0zehEkd7QR\n" + + "t7Aq38ixCQyxCmNIDJeDCKJT+wwdLaKuw/4SEpR9sygSxZ3kG6kF4icsgYuiOCRx\n" + + "+DrS1wP9kcrQVWQ0bJbGzwxLZXCHaJsWE1Y17mQAO4Iv/9icqDkP3bZBU5GCgbNT\n" + + "JEP2GiUUPU3nL41Tlq03+iDmkS2bpWCtFZmTgUg+1nJEb7PSCJ9VcoflOOFgX/ku\n" + + "TQCJWwhsgyOneEZAg7PpzOj2msxA9RWI88FzRnX/zyjWEpdUCVJ85hFw8u+UZ7k1\n" + + "eF37oOpgNxQMJ+/ey7huneTzyhpFz/TqJpfMmwaGbPL6zmPLAMQalIPQj+68zlcX\n" + + "qyeKVbZU74Vm051kXb/3qs6CeUpT4HrY3UmHWLvOdNkCAwEAAaOCAiUwggIhMB8G\n" + + "A1UdIwQYMBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAn\n" + + "BggrBgEFBQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUF\n" + + "BzAChiFodHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAE\n" + + "ggElMIIBITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6\n" + + "Ly9yZXBvc2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRy\n" + + "dXN0IENlcnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kg\n" + + "VFMgMTAyIDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlv\n" + + "biBieSBDU1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRh\n" + + "IG9yIEVudGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAI\n" + + "BgYEAI96AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5s\n" + + "dS9MVEdRQ0EzLmNybDARBgNVHQ4ECgQISND+8GZyXrcwDgYDVR0PAQH/BAQDAgTw\n" + + "MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAA54w2kGy+hJsYSyrQ5C\n" + + "ft0rasUHQviEiy31H2Z1lh4yEPLiuUsaepdzG4bov/J1RewX1fL7fvErraKK7nNr\n" + + "ioAXNElHtC0wfxGx0xGaCz7xsZIDFgpzyPqS+vd8VKbRCOY66AI+3aPiatCsk+BM\n" + + "Hp9GwW3B1e5EOgXiWVNxzYFtav5QSAj28IEV7ZuN2BIiU+phawRaoFy+4glMB7zE\n" + + "J5AM/Zfi50Q85ljy1kWUueFE3VNDafAUGOF5gTHvkKqj6LznUkqcT8m96Wd0IbF2\n" + + "BLYjnKPF6lGJsivErGqMwQIhlUUMkRQ13/hftL12rIiSjC1C/6cnbxOjWEOGnler\n" + + "Qn2zu2OTGnnrYxp/hojdZggb5Yt9mkM3EmyuqP1W4g0xtMv9q97swm/fHz/rDh8T\n" + + "MqrEOJzz284IM0DXjXq1wkmsZ/6/ueCyf0oBN0csvYspZKmLAydZ+jZmjdKKxX+N\n" + + "dreauHgOq1knLHkMb/YIyA+Oh6SBlNXL4Iae8APQcRGnylHQ1lc/YHTqWh8N1tmn\n" + + "no5r1kVJBYYtkI3oufaLtP7JIazteZlqTN+tubMJhO4xGgt6bqEpQiid9r3UnIjR\n" + + "esLYxXS5qRwSoOSleXT98H75+Ok1WR3ciD4exBR8/KcUtDITvDJhkBHnRHm40jFs\n" + + "5UbHFf98S6G9dqzsqW8+2Bpn\n" + + "-----END CERTIFICATE-----"; + + // Owner: T=Private Person, SERIALNUMBER=00100918135105608625, + // GIVENNAME=TokenPRIREV, SURNAME=Test, CN=TokenPRIREV Test, C=LU + // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU + // Serial number: 3814b8 + // Valid from: Wed Jul 10 04:36:48 PDT 2019 until: Sun Jul 10 04:36:48 PDT 2022 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIG+DCCBOCgAwIBAgIDOBS4MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" + + "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" + + "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjQ4WhcNMjIwNzEwMTEzNjQ4\n" + + "WjCBhTELMAkGA1UEBhMCTFUxGTAXBgNVBAMTEFRva2VuUFJJUkVWIFRlc3QxDTAL\n" + + "BgNVBAQTBFRlc3QxFDASBgNVBCoTC1Rva2VuUFJJUkVWMR0wGwYDVQQFExQwMDEw\n" + + "MDkxODEzNTEwNTYwODYyNTEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24wggGiMA0G\n" + + "CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCcm7y4c/D58u6g3m6HGdfiqDXa2yEl\n" + + "H2cAeSb85fsAX08iXfa/U/kmFqqycwp2nsJdfor6HEEqHsmozyjjIWHDEsq+cUre\n" + + "SO6d2Ag29MrxsAWZ1XAol40FcxNN+yEL9Xs5doqqcbz3OoKdxkoWVdYq3D7peizF\n" + + "OER4M2XA0KSLiKXDapDCfTVLE6qRG6Cn5mqnlqbUtkI6vSsda5mWLSNe4Qw/PIMw\n" + + "v7ZDn5dHeHoV6UpZC95Ole5vMQfjAOsy4nRc1zofQz7iPw4ClNzDQSuonaAKSk3Y\n" + + "1KjWPmHshb6BoANL+ce1KuWESKV3D5lBkVVLTeoBkWQu7ViJviF2HE5UoPRSGijO\n" + + "nmGOTZRsjOJXPe7/pEq9SQ477EufnSsoCj1cPCtaowbsO7oswzV/axKMhhZf6nU7\n" + + "0wd9xUuMgMRKBfi026mYK7pdxJ85qE8qKlqeNprje+g1sjxMDbMHARA427Px0IUJ\n" + + "mzIJk0ysAQvbqQVe8QQM/f+PH3mUkXR02H8CAwEAAaOCAiUwggIhMB8GA1UdIwQY\n" + + "MBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAnBggrBgEF\n" + + "BQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFo\n" + + "dHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAEggElMIIB\n" + + "ITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBv\n" + + "c2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRydXN0IENl\n" + + "cnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kgVFMgMTAy\n" + + "IDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlvbiBieSBD\n" + + "U1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRhIG9yIEVu\n" + + "dGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAIBgYEAI96\n" + + "AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5sdS9MVEdR\n" + + "Q0EzLmNybDARBgNVHQ4ECgQIS0KUXpWyku0wDgYDVR0PAQH/BAQDAgTwMAwGA1Ud\n" + + "EwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAFSnezuyeRO0sh9e8/1N+2RE6Uhb\n" + + "RIdLKmaS8hMOyUNBapnHfJAdOn7j767qWQjRop5VNCcv0zDOxAqApxFiz4gJdzBY\n" + + "FVrEVwYos8a3BHLXNxfwIWEJ6EjlqI2qI3NjqK8m4M8LTq4G94V2/MOFVpXeCLju\n" + + "r0s+XZep2Sk9J4ofUOc8Gp7IZNhPzIlfKQ+KhnWovde4bpL3zRpp4u7Y580XsBuN\n" + + "kow2Eg84tRzSVizmgLPuRbySHuMo1jGIP7F9FdtOC8VVSjntfCXSEQqOvpH4YZ8S\n" + + "V4qP17CQHPWW1kOHAyXpkAjU+6SOlmF76Adv9nQFTZ6DAnKqiuxmi8EVCv96aFD7\n" + + "Ih+zBF7kj7fghPjUzsVdB6gI4VwuFCXEaAfWlxJS67s1hKnsCyqX3cu+Gnq9aRt+\n" + + "08iaTVEdrKL95AYYobVbnGJ7bH87SpenjLL+CDctXNNDlpJZ8eRYcQe+Q4dg+8L8\n" + + "X8tkXBeRbiZD1U7XwVBnKF6sJmhA4F/h/EJzwX0lp7EU6EO91bSiwD2NFVs+64UR\n" + + "9lftfFFm5In2N3vjDR/3nrCf3Jq9f0g7bTrNJmo+hc0+fD+zlAhZAx+ii2xE1cY1\n" + + "KLH2zXNzPUgIqYGdVQwn1TUFJN8JgGKsXwc+P51nEpgf6JVyK1m7EtVGtr9gF7DI\n" + + "P+4VSqTbTp4/l5n0\n" + + "-----END CERTIFICATE-----"; + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Wed Jul 10 04:48:49 PDT 2019", System.out); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/IOUtils/ReadAllBytes.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/IOUtils/ReadAllBytes.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/IOUtils/ReadAllBytes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/IOUtils/ReadAllBytes.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Random; + +import jdk.testlibrary.RandomFactory; + +import sun.misc.IOUtils; + +/* + * @test + * @bug 8080835 8193832 + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main ReadAllBytes + * @summary Basic test for IOUtils.readAllBytes + * @key randomness + */ + +public class ReadAllBytes { + + private static Random generator = RandomFactory.getRandom(); + + public static void main(String[] args) throws IOException { + test(new byte[]{}); + test(new byte[]{1, 2, 3}); + test(createRandomBytes(1024)); + for (int shift : new int[] {13, 14, 15, 17}) { + for (int offset : new int[] {-1, 0, 1}) { + test(createRandomBytes((1 << shift) + offset)); + } + } + } + + static void test(byte[] expectedBytes) throws IOException { + int expectedLength = expectedBytes.length; + WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(expectedBytes)); + byte[] readBytes = IOUtils.readAllBytes(in); + + int x; + byte[] tmp = new byte[10]; + check((x = in.read()) == -1, + "Expected end of stream from read(), got " + x); + check((x = in.read(tmp)) == -1, + "Expected end of stream from read(byte[]), got " + x); + check((x = in.read(tmp, 0, tmp.length)) == -1, + "Expected end of stream from read(byte[], int, int), got " + x); + check(IOUtils.readAllBytes(in).length == 0, + "Expected readAllBytes to return empty byte array"); + check(expectedLength == readBytes.length, + "Expected length " + expectedLength + ", got " + readBytes.length); + check(Arrays.equals(expectedBytes, readBytes), + "Expected[" + expectedBytes + "], got:[" + readBytes + "]"); + check(!in.isClosed(), "Stream unexpectedly closed"); + } + + static byte[] createRandomBytes(int size) { + byte[] bytes = new byte[size]; + generator.nextBytes(bytes); + return bytes; + } + + static void check(boolean cond, Object ... failedArgs) { + if (cond) + return; + StringBuilder sb = new StringBuilder(); + for (Object o : failedArgs) + sb.append(o); + throw new RuntimeException(sb.toString()); + } + + static class WrapperInputStream extends FilterInputStream { + private boolean closed; + WrapperInputStream(InputStream in) { super(in); } + @Override public void close() throws IOException { closed = true; in.close(); } + boolean isClosed() { return closed; } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/IOUtils/ReadNBytes.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/IOUtils/ReadNBytes.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/IOUtils/ReadNBytes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/IOUtils/ReadNBytes.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015, 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Random; +import jdk.testlibrary.RandomFactory; + +import sun.misc.IOUtils; + +/* + * @test + * @bug 8080835 8139206 + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main ReadNBytes + * @summary Basic test for IOUtils.readNBytes + * @key randomness + */ + +public class ReadNBytes { + + private static Random generator = RandomFactory.getRandom(); + + public static void main(String[] args) throws IOException { + test(new byte[]{1, 2, 3}); + test(createRandomBytes(1024)); + for (int shift : new int[] {13, 15, 17}) { + for (int offset : new int[] {-1, 0, 1}) { + test(createRandomBytes((1 << shift) + offset)); + } + } + + test(-1); + test(0); + for (int shift : new int[] {13, 15, 17}) { + for (int offset : new int[] {-1, 0, 1}) { + test((1 << shift) + offset); + } + } + } + + static void test(byte[] inputBytes) throws IOException { + int length = inputBytes.length; + WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(inputBytes)); + byte[] readBytes = new byte[(length / 2) + 1]; + int nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length); + + int x; + byte[] tmp; + check(nread == readBytes.length, + "Expected number of bytes read: " + readBytes.length + ", got: " + nread); + check(Arrays.equals((tmp = Arrays.copyOf(inputBytes, nread)), readBytes), + "Expected[" + tmp + "], got:[" + readBytes + "]"); + check(!in.isClosed(), "Stream unexpectedly closed"); + + // Read again + nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length); + + check(nread == length - readBytes.length, + "Expected number of bytes read: " + (length - readBytes.length) + ", got: " + nread); + check(Arrays.equals((tmp = Arrays.copyOfRange(inputBytes, readBytes.length, length)), + Arrays.copyOf(readBytes, nread)), + "Expected[" + tmp + "], got:[" + readBytes + "]"); + // Expect end of stream + check((x = in.read()) == -1, + "Expected end of stream from read(), got " + x); + check((x = in.read(tmp)) == -1, + "Expected end of stream from read(byte[]), got " + x); + check((x = in.read(tmp, 0, tmp.length)) == -1, + "Expected end of stream from read(byte[], int, int), got " + x); + check((x = IOUtils.readNBytes(in, tmp, 0, tmp.length)) == 0, + "Expected end of stream, 0, from readNBytes(byte[], int, int), got " + x); + check(!in.isClosed(), "Stream unexpectedly closed"); + } + + static void test(int max) throws IOException { + byte[] subset1, subset2; + byte[] inputBytes = max <= 0 ? new byte[0] : createRandomBytes(max); + WrapperInputStream in = + new WrapperInputStream(new ByteArrayInputStream(inputBytes)); + + if (max < 0) { + try { + IOUtils.readNBytes(in, max); + check(false, "Expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException iae) { + return; + } + } else if (max == 0) { + int x; + check((x = IOUtils.readNBytes(in, max).length) == 0, + "Expected zero bytes, got " + x); + return; + } + + int off = Math.toIntExact(in.skip(generator.nextInt(max/2))); + int len = generator.nextInt(max - 1 - off); + byte[] readBytes = IOUtils.readNBytes(in, len); + check(readBytes.length == len, + "Expected " + len + " bytes, got " + readBytes.length); + subset1 = Arrays.copyOfRange(inputBytes, off, off + len); + subset2 = Arrays.copyOfRange(readBytes, 0, len); + check(Arrays.equals(subset1, subset2), "Expected[" + subset1 + + "], got:[" + readBytes + "]"); + + int remaining = max - (off + len); + readBytes = IOUtils.readNBytes(in, remaining); + check(readBytes.length == remaining, + "Expected " + remaining + "bytes, got " + readBytes.length); + subset1 = Arrays.copyOfRange(inputBytes, off + len, max); + subset2 = Arrays.copyOfRange(readBytes, 0, remaining); + check(Arrays.equals(subset1, subset2), "Expected[" + subset1 + + "], got:[" + readBytes + "]"); + + check(!in.isClosed(), "Stream unexpectedly closed"); + } + + static byte[] createRandomBytes(int size) { + byte[] bytes = new byte[size]; + generator.nextBytes(bytes); + return bytes; + } + + static void check(boolean cond, Object ... failedArgs) { + if (cond) + return; + StringBuilder sb = new StringBuilder(); + for (Object o : failedArgs) + sb.append(o); + throw new RuntimeException(sb.toString()); + } + + + static class WrapperInputStream extends FilterInputStream { + private boolean closed; + WrapperInputStream(InputStream in) { super(in); } + @Override public void close() throws IOException { closed = true; in.close(); } + boolean isClosed() { return closed; } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/URLClassPath/JarClassPathFileEntry.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/URLClassPath/JarClassPathFileEntry.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/misc/URLClassPath/JarClassPathFileEntry.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/misc/URLClassPath/JarClassPathFileEntry.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import jdk.testlibrary.InMemoryJavaCompiler; +import jdk.testlibrary.JarUtils; + +/* + * @test + * @bug 8216401 + * @summary Test loading of JAR Class-Path entry with file: scheme + * @library /lib/testlibrary + * + * @run main/othervm JarClassPathFileEntry + * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=true JarClassPathFileEntry + * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=false JarClassPathFileEntry + */ + +public class JarClassPathFileEntry { + private final static boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows"); + + private final static String TEST_CLASSES = System.getProperty("test.classes"); + private final static String OTHER_DIR = TEST_CLASSES + "/OTHER/"; + + private final static Path OTHER_JAR_PATH = Paths.get(OTHER_DIR, "Other.jar"); + private final static Path CONTEXT_JAR_PATH = Paths.get(TEST_CLASSES, "Context.jar"); + + public static void main(String[] args) throws Throwable { + // Create Other.class in OTHER_DIR, off the default classpath + byte klassbuf[] = InMemoryJavaCompiler.compile("Other", + "public class Other {}"); + ClassFileInstaller.writeClassToDisk("Other", klassbuf, OTHER_DIR); + + // Create Other.jar in OTHER_DIR + JarUtils.createJarFile(OTHER_JAR_PATH, + Paths.get(OTHER_DIR), + Paths.get(OTHER_DIR, "Other.class")); + + // Create Context.class + klassbuf = InMemoryJavaCompiler.compile("Context", + "public class Context {}"); + ClassFileInstaller.writeClassToDisk("Context", klassbuf, TEST_CLASSES); + + // Create Context.jar w/ "file:" entry for Other.jar + Manifest mf = new Manifest(); + Attributes attrs = mf.getMainAttributes(); + attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + + String classPathEntry = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString()) + : OTHER_JAR_PATH.toString()); + attrs.put(Attributes.Name.CLASS_PATH, classPathEntry); + + System.out.println("Creating Context.jar with Class-Path: " + classPathEntry); + JarUtils.createJarFile(CONTEXT_JAR_PATH, mf, + Paths.get(TEST_CLASSES), + Paths.get(TEST_CLASSES, "Context.class")); + + // Use URLClassLoader w/ Context.jar to load Other.class, which will + // load via the Class-Path entry + URL url = CONTEXT_JAR_PATH.toUri().toURL(); + URLClassLoader ucl = new URLClassLoader(new URL[]{ url }, + null); // don't delegate to App CL + Class otherClass = Class.forName("Other", true, ucl); // ClassNotFoundException -> fail + System.out.println("Loaded: " + otherClass); + } + + /* Convert a Windows path to a unix-style path, and remove any drive letter */ + private static String toUnixPath(String orig) { + String retVal = new File(orig).toURI().getPath(); + int colonAt = retVal.indexOf(':'); + + if (colonAt != -1 && colonAt < 3) { + retVal = retVal.substring(colonAt + 1); // Start after the drive letter + } + return retVal; + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/net/www/B8185898.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/net/www/B8185898.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/net/www/B8185898.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/net/www/B8185898.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8185898 + * @library /lib/testlibrary + * @run main/othervm B8185898 + * @summary setRequestProperty(key, null) results in HTTP header without colon in request + */ + +import java.io.*; +import java.net.*; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.Collections; + +import jdk.testlibrary.net.URIBuilder; +import sun.net.www.MessageHeader; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.nio.charset.StandardCharsets.UTF_8; + +/* + * Test checks that MessageHeader with key != null and value == null is set correctly + * and printed according to HTTP standard in the format : + * */ +public class B8185898 { + + static HttpServer server; + static final String RESPONSE_BODY = "Test response body"; + static final String H1 = "X-header1"; + static final String H2 = "X-header2"; + static final String VALUE = "This test value should appear"; + static final List oneList = Arrays.asList(VALUE); + static final List zeroList = Arrays.asList(""); + static int port; + static URL url; + static volatile Map> headers; + + static class Handler implements HttpHandler { + + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + InetSocketAddress rem = t.getRemoteAddress(); + headers = t.getRequestHeaders(); // Get request headers on the server side + while(is.read() != -1){} + is.close(); + + OutputStream os = t.getResponseBody(); + t.sendResponseHeaders(200, RESPONSE_BODY.length()); + os.write(RESPONSE_BODY.getBytes(UTF_8)); + t.close(); + } + } + + public static void main(String[] args) throws Exception { + ExecutorService exec = Executors.newCachedThreadPool(); + InetAddress loopback = InetAddress.getLoopbackAddress(); + + try { + InetSocketAddress addr = new InetSocketAddress(loopback, 0); + server = HttpServer.create(addr, 100); + HttpHandler handler = new Handler(); + HttpContext context = server.createContext("/", handler); + server.setExecutor(exec); + server.start(); + + port = server.getAddress().getPort(); + System.out.println("Server on port: " + port); + url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/foo") + .toURLUnchecked(); + System.out.println("URL: " + url); + testMessageHeader(); + testMessageHeaderMethods(); + testURLConnectionMethods(); + } finally { + server.stop(0); + System.out.println("After server shutdown"); + exec.shutdown(); + } + } + + // Test message header with malformed message header and fake request line + static void testMessageHeader() { + final String badHeader = "This is not a request line for HTTP/1.1"; + final String fakeRequestLine = "This /is/a/fake/status/line HTTP/2.0"; + final String expectedHeaders = fakeRequestLine + "\r\n" + + H1 + ": " + VALUE + "\r\n" + + H2 + ": " + VALUE + "\r\n" + + badHeader + ":\r\n\r\n"; + + MessageHeader header = new MessageHeader(); + header.add(H1, VALUE); + header.add(H2, VALUE); + header.add(badHeader, null); + header.prepend(fakeRequestLine, null); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + header.print(new PrintStream(out)); + + if (!out.toString().equals(expectedHeaders)) { + throw new AssertionError("FAILED: expected: " + + expectedHeaders + "\nReceived: " + out.toString()); + } else { + System.out.println("PASSED: ::print returned correct " + + "status line and headers:\n" + out.toString()); + } + } + + // Test MessageHeader::print, ::toString, implicitly testing that + // MessageHeader::mergeHeader formats headers correctly for responses + static void testMessageHeaderMethods() throws IOException { + // {{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" + + "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}" + + "{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" + + "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" + + "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}" + + "{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" + + "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"}, + }; + + System.out.println("Test custom message headers"); + for (String[] s : strings) { + // Test MessageHeader::toString + MessageHeader header = new MessageHeader( + new ByteArrayInputStream(s[0].getBytes(ISO_8859_1))); + if (!header.toString().endsWith(s[1])) { + throw new AssertionError("FAILED: expected: " + + s[1] + "\nReceived: " + header); + } else { + System.out.println("PASSED: ::toString returned correct " + + "status line and headers:\n" + header); + } + + // Test MessageHeader::print + ByteArrayOutputStream out = new ByteArrayOutputStream(); + header.print(new PrintStream(out)); + if (!out.toString().equals(s[2])) { + throw new AssertionError("FAILED: expected: " + + s[2] + "\nReceived: " + out.toString()); + } else { + System.out.println("PASSED: ::print returned correct " + + "status line and headers:\n" + out.toString()); + } + } + } + + // Test methods URLConnection::getRequestProperties, + // ::getHeaderField, ::getHeaderFieldKey + static void testURLConnectionMethods() throws IOException { + HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); + urlConn.setRequestProperty(H1, ""); + urlConn.setRequestProperty(H1, VALUE); + urlConn.setRequestProperty(H2, null); // Expected to contain ':' between key and value + Map> props = urlConn.getRequestProperties(); + Map> expectedMap = new HashMap>(); + expectedMap.put(H1, oneList); + expectedMap.put(H2, Arrays.asList((String)null)); + + // Test request properties + System.out.println("Client request properties"); + StringBuilder sb = new StringBuilder(); + props.forEach((k, v) -> sb.append(k + ": " + + v.stream().collect(Collectors.joining()) + "\n")); + System.out.println(sb); + + if (!props.equals(expectedMap)) { + throw new AssertionError("Unexpected properties returned: " + + props); + } else { + System.out.println("Properties returned as expected"); + } + + // Test header fields + String headerField = urlConn.getHeaderField(0); + if (!headerField.contains("200 OK")) { + throw new AssertionError("Expected headerField[0]: status line. " + + "Received: " + headerField); + } else { + System.out.println("PASSED: headerField[0] contains status line: " + + headerField); + } + + String headerFieldKey = urlConn.getHeaderFieldKey(0); + if (headerFieldKey != null) { + throw new AssertionError("Expected headerFieldKey[0]: null. " + + "Received: " + headerFieldKey); + } else { + System.out.println("PASSED: headerFieldKey[0] is null"); + } + + // Check that test request headers are included with correct format + try ( + BufferedReader in = new BufferedReader( + new InputStreamReader(urlConn.getInputStream())) + ) { + if (!headers.keySet().contains(H1)) { + throw new AssertionError("Expected key not found: " + + H1 + ": " + VALUE); + } else if (!headers.get(H1).equals(oneList)) { + throw new AssertionError("Unexpected key-value pair: " + + H1 + ": " + headers.get(H1)); + } else { + System.out.println("PASSED: " + H1 + " included in request headers"); + } + + if (!headers.keySet().contains(H2)) { + throw new AssertionError("Expected key not found: " + + H2 + ": "); + // Check that empty list is returned + } else if (!headers.get(H2).equals(zeroList)) { + throw new AssertionError("Unexpected key-value pair: " + + H2 + ": " + headers.get(H2)); + } else { + System.out.println("PASSED: " + H2 + " included in request headers"); + } + + String inputLine; + while ((inputLine = in.readLine()) != null) { + System.out.println(inputLine); + } + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ec/SignatureDigestTruncate.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ec/SignatureDigestTruncate.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ec/SignatureDigestTruncate.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ec/SignatureDigestTruncate.java 2020-01-15 20:05:09.000000000 +0000 @@ -91,22 +91,25 @@ String privateKeyStr, String msgStr, String kStr, String sigStr) throws Exception { + System.out.println("Testing " + alg + " with " + curveName); + byte[] privateKey = Convert.hexStringToByteArray(privateKeyStr); byte[] msg = Convert.hexStringToByteArray(msgStr); byte[] k = Convert.hexStringToByteArray(kStr); byte[] expectedSig = Convert.hexStringToByteArray(sigStr); - AlgorithmParameters params = AlgorithmParameters.getInstance("EC"); + AlgorithmParameters params = + AlgorithmParameters.getInstance("EC", "SunEC"); params.init(new ECGenParameterSpec(curveName)); ECParameterSpec ecParams = params.getParameterSpec(ECParameterSpec.class); - KeyFactory kf = KeyFactory.getInstance("EC"); + KeyFactory kf = KeyFactory.getInstance("EC", "SunEC"); BigInteger s = new BigInteger(1, privateKey); ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(s, ecParams); PrivateKey privKey = kf.generatePrivate(privKeySpec); - Signature sig = Signature.getInstance(alg); + Signature sig = Signature.getInstance(alg, "SunEC"); sig.initSign(privKey, new FixedRandom(k)); sig.update(msg); byte[] computedSig = sig.sign(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Addresses.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Addresses.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Addresses.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Addresses.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031111 + * @summary fix krb5 caddr + * @compile -XDignore.symbol.file Addresses.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Addresses + */ + +import sun.security.krb5.Config; + +import javax.security.auth.kerberos.KerberosTicket; +import java.net.Inet4Address; +import java.net.InetAddress; + +public class Addresses { + + public static void main(String[] args) throws Exception { + + KDC.saveConfig(OneKDC.KRB5_CONF, new OneKDC(null), + "noaddresses = false", + "extra_addresses = 10.0.0.10, 10.0.0.11 10.0.0.12"); + Config.refresh(); + + KerberosTicket ticket = + Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false) + .s().getPrivateCredentials(KerberosTicket.class) + .iterator().next(); + + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetAddress extra1 = InetAddress.getByName("10.0.0.10"); + InetAddress extra2 = InetAddress.getByName("10.0.0.11"); + InetAddress extra3 = InetAddress.getByName("10.0.0.12"); + + boolean loopbackFound = false; + boolean extra1Found = false; + boolean extra2Found = false; + boolean extra3Found = false; + boolean networkFound = false; + + for (InetAddress ia: ticket.getClientAddresses()) { + System.out.println(ia); + if (ia.equals(loopback)) { + loopbackFound = true; + System.out.println(" loopback found"); + } else if (ia.equals(extra1)) { + extra1Found = true; + System.out.println(" extra1 found"); + } else if (ia.equals(extra2)) { + extra2Found = true; + System.out.println(" extra2 found"); + } else if (ia.equals(extra3)) { + extra3Found = true; + System.out.println(" extra3 found"); + } else if (ia instanceof Inet4Address) { + networkFound = true; + System.out.println(" another address (" + ia + + "), assumed real network"); + } + } + + if (!loopbackFound || !networkFound + || !extra1Found || !extra2Found || !extra3Found ) { + throw new Exception(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Basic.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Basic.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Basic.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Basic.java 2020-01-15 20:05:09.000000000 +0000 @@ -23,10 +23,12 @@ /* * @test - * @bug 7152176 + * @bug 7152176 8201627 * @summary More krb5 tests * @compile -XDignore.symbol.file Basic.java - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Basic + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock + * -Dsun.security.krb5.acceptor.sequence.number.nonmutual=zero + * Basic */ import sun.security.jgss.GSSUtil; @@ -45,6 +47,7 @@ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); c.x().requestCredDeleg(true); + c.x().requestMutualAuth(false); s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); Context.handshake(c, s); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/BasicKrb5Test.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/BasicKrb5Test.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/BasicKrb5Test.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/BasicKrb5Test.java 2020-01-15 20:05:09.000000000 +0000 @@ -79,7 +79,7 @@ String etype = null; for (String arg: args) { if (arg.equals("-s")) Context.usingStream = true; - else if(arg.equals("-C")) conf = false; + else if (arg.equals("-C")) conf = false; else etype = arg; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/BasicProc.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/BasicProc.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/BasicProc.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/BasicProc.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * 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,180 +23,306 @@ /* * @test - * @bug 8009977 - * @summary A test library to launch multiple Java processes - * @library ../../../../java/security/testlibrary/ + * @bug 8009977 8186884 8201627 + * @summary A test to launch multiple Java processes using either Java GSS + * or native GSS + * @library ../../../../java/security/testlibrary /lib/testlibrary * @compile -XDignore.symbol.file BasicProc.java - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc launcher */ -import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermission; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.PropertyPermission; +import java.util.Set; + +import jdk.testlibrary.Asserts; import org.ietf.jgss.Oid; +import sun.security.krb5.Config; import javax.security.auth.PrivateCredentialPermission; +/** + * Run this test automatically and test Java GSS with embedded KDC. + * + * Run with customized native.krb5.libs to test interop between Java GSS + * and native GSS, and native.kdc.path with a native KDC. For example, + * run the following command to test interop among Java, default native, + * MIT, and Heimdal krb5 libraries with the Heimdal KDC: + * + * jtreg -Dnative.krb5.libs=j=, + * n=, + * k=/usr/local/krb5/lib/libgssapi_krb5.so, + * h=/space/install/heimdal/lib/libgssapi.so \ + * -Dnative.kdc.path=/usr/local/heimdal \ + * BasicProc.java + * + * Note: The first 4 lines should be concatenated to make a long system + * property value with no blank around ",". This comma-separated value + * has each element being name=libpath. The special name "j" means the + * Java library and libpath is ignored. Otherwise it means a native library, + * and libpath (can be empty) will be the value for the sun.security.jgss.lib + * system property. If this system property is not set, only the Java + * library will be tested. + */ + public class BasicProc { - static String CONF = "krb5.conf"; - static String KTAB = "ktab"; + private static final String CONF = "krb5.conf"; + private static final String KTAB_S = "server.ktab"; + private static final String KTAB_B = "backend.ktab"; + + private static final String HOST = "localhost"; + private static final String SERVER = "server/" + HOST; + private static final String BACKEND = "backend/" + HOST; + private static final String USER = "user"; + private static final char[] PASS = "password".toCharArray(); + private static final String REALM = "REALM"; + + private static final int MSGSIZE = 1024; + private static final byte[] MSG = new byte[MSGSIZE]; + public static void main(String[] args) throws Exception { - String HOST = "localhost"; - String SERVER = "server/" + HOST; - String BACKEND = "backend/" + HOST; - String USER = "user"; - char[] PASS = "password".toCharArray(); - String REALM = "REALM"; Oid oid = new Oid("1.2.840.113554.1.2.2"); + byte[] token, msg; - if (args.length == 0) { - System.setProperty("java.security.krb5.conf", CONF); - KDC kdc = KDC.create(REALM, HOST, 0, true); - kdc.addPrincipal(USER, PASS); - kdc.addPrincipalRandKey("krbtgt/" + REALM); - kdc.addPrincipalRandKey(SERVER); - kdc.addPrincipalRandKey(BACKEND); - - String cwd = System.getProperty("user.dir"); - kdc.writeKtab(KTAB); - KDC.saveConfig(CONF, kdc, "forwardable = true"); - - Proc pc = Proc.create("BasicProc") - .args("client") - .prop("java.security.krb5.conf", CONF) - .prop("java.security.manager", "") - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") - .perm(new java.lang.RuntimePermission( - "accessClassInPackage.sun.net.spi.nameservice")) - .perm(new java.util.PropertyPermission( - "sun.security.krb5.principal", "read")) - .perm(new javax.security.auth.AuthPermission( - "modifyPrincipals")) - .perm(new javax.security.auth.AuthPermission( - "modifyPrivateCredentials")) - .perm(new javax.security.auth.AuthPermission("doAs")) - .perm(new javax.security.auth.kerberos.ServicePermission( - "krbtgt/" + REALM + "@" + REALM, "initiate")) - .perm(new javax.security.auth.kerberos.ServicePermission( - "server/localhost@" + REALM, "initiate")) - .perm(new javax.security.auth.kerberos.DelegationPermission( - "\"server/localhost@" + REALM + "\" " + - "\"krbtgt/" + REALM + "@" + REALM + "\"")) - .debug("C") - .start(); - Proc ps = Proc.create("BasicProc") - .args("server") - .prop("java.security.krb5.conf", CONF) - .prop("java.security.manager", "") - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") - .perm(new java.lang.RuntimePermission( - "accessClassInPackage.sun.net.spi.nameservice")) - .perm(new java.util.PropertyPermission( + switch (args[0]) { + case "launcher": + KDC kdc = KDC.create(REALM, HOST, 0, true); + try { + kdc.addPrincipal(USER, PASS); + kdc.addPrincipalRandKey("krbtgt/" + REALM); + kdc.addPrincipalRandKey(SERVER); + kdc.addPrincipalRandKey(BACKEND); + + // Native lib might do some name lookup + KDC.saveConfig(CONF, kdc, + "dns_lookup_kdc = no", + "ticket_lifetime = 1h", + "dns_lookup_realm = no", + "dns_canonicalize_hostname = false", + "forwardable = true"); + System.setProperty("java.security.krb5.conf", CONF); + Config.refresh(); + kdc.writeKtab(KTAB_S, false, SERVER); + kdc.writeKtab(KTAB_B, false, BACKEND); + + String[] tmp = System.getProperty("native.krb5.libs", "j=") + .split(","); + + // Library paths. The 1st one is always null which means + // Java, "" means the default native lib. + String[] libs = new String[tmp.length]; + + // Names for each lib above. Use in file names. + String[] names = new String[tmp.length]; + + boolean hasNative = false; + + for (int i = 0; i < tmp.length; i++) { + if (tmp[i].isEmpty()) { + throw new Exception("Invalid native.krb5.libs"); + } + String[] pair = tmp[i].split("=", 2); + names[i] = pair[0]; + if (!pair[0].equals("j")) { + libs[i] = pair.length > 1 ? pair[1] : ""; + hasNative = true; + } + } + + if (hasNative) { + kdc.kinit(USER, "base.ccache"); + } + + // Try the same lib first + for (int i = 0; i < libs.length; i++) { + once(names[i] + names[i] + names[i], + libs[i], libs[i], libs[i]); + } + + for (int i = 0; i < libs.length; i++) { + for (int j = 0; j < libs.length; j++) { + for (int k = 0; k < libs.length; k++) { + if (i != j || i != k) { + once(names[i] + names[j] + names[k], + libs[i], libs[j], libs[k]); + } + } + } + } + } finally { + kdc.terminate(); + } + break; + case "client": + Context c = args[1].equals("n") ? + Context.fromThinAir() : + Context.fromUserPass(USER, PASS, false); + c.startAsClient(SERVER, oid); + c.x().requestCredDeleg(true); + c.x().requestMutualAuth(true); + Proc.binOut(c.take(new byte[0])); // AP-REQ + c.take(Proc.binIn()); // AP-REP + Proc.binOut(c.wrap(MSG, true)); + Proc.binOut(c.getMic(MSG)); + break; + case "server": + Context s = args[1].equals("n") ? + Context.fromThinAir() : + Context.fromUserKtab(SERVER, KTAB_S, true); + s.startAsServer(oid); + token = Proc.binIn(); // AP-REQ + Proc.binOut(s.take(token)); // AP-REP + msg = s.unwrap(Proc.binIn(), true); + Asserts.assertTrue(Arrays.equals(msg, MSG)); + s.verifyMic(Proc.binIn(), msg); + Context s2 = s.delegated(); + s2.startAsClient(BACKEND, oid); + s2.x().requestMutualAuth(false); + Proc.binOut(s2.take(new byte[0])); // AP-REQ + msg = s2.unwrap(Proc.binIn(), true); + Asserts.assertTrue(Arrays.equals(msg, MSG)); + s2.verifyMic(Proc.binIn(), msg); + break; + case "backend": + Context b = args[1].equals("n") ? + Context.fromThinAir() : + Context.fromUserKtab(BACKEND, KTAB_B, true); + b.startAsServer(oid); + token = b.take(Proc.binIn()); // AP-REQ + Asserts.assertTrue(token == null); + Proc.binOut(b.wrap(MSG, true)); + Proc.binOut(b.getMic(MSG)); + break; + } + } + + /** + * One test run. + * + * @param label test label + * @param lc lib of client + * @param ls lib of server + * @param lb lib of backend + */ + private static void once(String label, String lc, String ls, String lb) + throws Exception { + + Proc pc = proc(lc) + .args("client", lc == null ? "j" : "n") + .perm(new javax.security.auth.kerberos.ServicePermission( + "krbtgt/" + REALM + "@" + REALM, "initiate")) + .perm(new javax.security.auth.kerberos.ServicePermission( + SERVER + "@" + REALM, "initiate")) + .perm(new javax.security.auth.kerberos.DelegationPermission( + "\"" + SERVER + "@" + REALM + "\" " + + "\"krbtgt/" + REALM + "@" + REALM + "\"")) + .debug(label + "-C"); + if (lc == null) { + // for Krb5LoginModule::promptForName + pc.perm(new PropertyPermission("user.name", "read")); + } else { + Files.copy(Paths.get("base.ccache"), Paths.get(label + ".ccache")); + Set perms = new HashSet<>(); + perms.add(PosixFilePermission.OWNER_READ); + perms.add(PosixFilePermission.OWNER_WRITE); + Files.setPosixFilePermissions(Paths.get(label + ".ccache"), + Collections.unmodifiableSet(perms)); + pc.env("KRB5CCNAME", label + ".ccache"); + // Do not try system ktab if ccache fails + pc.env("KRB5_KTNAME", "none"); + } + pc.start(); + + Proc ps = proc(ls) + .args("server", ls == null ? "j" : "n") + .perm(new javax.security.auth.kerberos.ServicePermission( + SERVER + "@" + REALM, "accept")) + .perm(new javax.security.auth.kerberos.ServicePermission( + BACKEND + "@" + REALM, "initiate")) + .debug(label + "-S"); + if (ls == null) { + ps.perm(new PrivateCredentialPermission( + "javax.security.auth.kerberos.KeyTab * \"*\"", "read")) + .perm(new java.io.FilePermission(KTAB_S, "read")); + } else { + ps.env("KRB5_KTNAME", KTAB_S); + } + ps.start(); + + Proc pb = proc(lb) + .args("backend", lb == null ? "j" : "n") + .perm(new javax.security.auth.kerberos.ServicePermission( + BACKEND + "@" + REALM, "accept")) + .debug(label + "-B"); + if (lb == null) { + pb.perm(new PrivateCredentialPermission( + "javax.security.auth.kerberos.KeyTab * \"*\"", "read")) + .perm(new java.io.FilePermission(KTAB_B, "read")); + } else { + pb.env("KRB5_KTNAME", KTAB_B); + } + pb.start(); + + // Client and server + ps.println(pc.readData()); // AP-REQ + pc.println(ps.readData()); // AP-REP + + ps.println(pc.readData()); // KRB-PRIV + ps.println(pc.readData()); // KRB-SAFE + + // Server and backend + pb.println(ps.readData()); // AP-REQ + + ps.println(pb.readData()); // KRB-PRIV + ps.println(pb.readData()); // KRB-SAFE + + if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) { + throw new Exception("Process failed"); + } + } + + /** + * A Proc for a child process. + * + * @param lib the library. Null is Java. "" is default native lib. + */ + private static Proc proc(String lib) throws Exception { + Proc p = Proc.create("BasicProc") + .prop("java.security.manager", "") + .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .perm(new javax.security.auth.AuthPermission("doAs")); + if (lib != null) { + p.env("KRB5_CONFIG", CONF) + .env("KRB5_TRACE", "/dev/stderr") + .prop("sun.security.jgss.native", "true") + .prop("sun.security.jgss.lib", lib) + .prop("javax.security.auth.useSubjectCredsOnly", "false") + .prop("sun.security.nativegss.debug", "true"); + int pos = lib.lastIndexOf('/'); + if (pos > 0) { + p.env("LD_LIBRARY_PATH", lib.substring(0, pos)); + p.env("DYLD_LIBRARY_PATH", lib.substring(0, pos)); + } + } else { + p.perm(new java.util.PropertyPermission( "sun.security.krb5.principal", "read")) - .perm(new javax.security.auth.AuthPermission( - "modifyPrincipals")) - .perm(new javax.security.auth.AuthPermission( - "modifyPrivateCredentials")) - .perm(new javax.security.auth.AuthPermission("doAs")) - .perm(new PrivateCredentialPermission( - "javax.security.auth.kerberos.KeyTab * \"*\"", - "read")) - .perm(new javax.security.auth.kerberos.ServicePermission( - "server/localhost@" + REALM, "accept")) - .perm(new java.io.FilePermission( - cwd + File.separator + KTAB, "read")) - .perm(new javax.security.auth.kerberos.ServicePermission( - "backend/localhost@" + REALM, "initiate")) - .debug("S") - .start(); - Proc pb = Proc.create("BasicProc") - .args("backend") - .prop("java.security.krb5.conf", CONF) - .prop("java.security.manager", "") - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + // For Krb5LoginModule::login. .perm(new java.lang.RuntimePermission( "accessClassInPackage.sun.net.spi.nameservice")) - .perm(new java.util.PropertyPermission( - "sun.security.krb5.principal", "read")) .perm(new javax.security.auth.AuthPermission( "modifyPrincipals")) .perm(new javax.security.auth.AuthPermission( "modifyPrivateCredentials")) - .perm(new javax.security.auth.AuthPermission("doAs")) - .perm(new PrivateCredentialPermission( - "javax.security.auth.kerberos.KeyTab * \"*\"", - "read")) - .perm(new javax.security.auth.kerberos.ServicePermission( - "backend/localhost@" + REALM, "accept")) - .perm(new java.io.FilePermission( - cwd + File.separator + KTAB, "read")) - .debug("B") - .start(); - - // Client and server handshake - String token = pc.readData(); - ps.println(token); - token = ps.readData(); - pc.println(token); - // Server and backend handshake - token = ps.readData(); - pb.println(token); - token = pb.readData(); - ps.println(token); - // wrap/unwrap/getMic/verifyMic and plain text - token = ps.readData(); - pb.println(token); - token = pb.readData(); - ps.println(token); - token = pb.readData(); - ps.println(token); - - if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) { - throw new Exception(); - } - } else if (args[0].equals("client")) { - Context c = Context.fromUserPass(USER, PASS, false); - c.startAsClient(SERVER, oid); - c.x().requestCredDeleg(true); - Proc.binOut(c.take(new byte[0])); - byte[] token = Proc.binIn(); - c.take(token); - } else if (args[0].equals("server")) { - Context s = Context.fromUserKtab(SERVER, KTAB, true); - s.startAsServer(oid); - byte[] token = Proc.binIn(); - token = s.take(token); - Proc.binOut(token); - Context s2 = s.delegated(); - s2.startAsClient(BACKEND, oid); - Proc.binOut(s2.take(new byte[0])); - token = Proc.binIn(); - s2.take(token); - byte[] msg = "Hello".getBytes(); - Proc.binOut(s2.wrap(msg, true)); - s2.verifyMic(Proc.binIn(), msg); - String in = Proc.textIn(); - if (!in.equals("Hello")) { - throw new Exception(); - } - } else if (args[0].equals("backend")) { - Context b = Context.fromUserKtab(BACKEND, KTAB, true); - b.startAsServer(oid); - byte[] token = Proc.binIn(); - Proc.binOut(b.take(token)); - byte[] msg = b.unwrap(Proc.binIn(), true); - Proc.binOut(b.getMic(msg)); - Proc.textOut(new String(msg)); + .prop("sun.security.krb5.debug", "true") + .prop("java.security.krb5.conf", CONF); } - } - // create a native server - private static Proc ns(Proc p) throws Exception { - return p - .env("KRB5_CONFIG", CONF) - .env("KRB5_KTNAME", KTAB) - .prop("sun.net.spi.nameservice.provider.1", "ns,mock") - .prop("sun.security.jgss.native", "true") - .prop("javax.security.auth.useSubjectCredsOnly", "false") - .prop("sun.security.nativegss.debug", "true"); + return p; } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Context.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Context.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Context.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Context.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,14 +22,21 @@ */ import com.sun.security.auth.module.Krb5LoginModule; -import java.security.Key; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.security.Key; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Set; import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.kerberos.KerberosKey; import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.login.LoginContext; @@ -40,6 +47,10 @@ import org.ietf.jgss.GSSName; import org.ietf.jgss.MessageProp; import org.ietf.jgss.Oid; +import sun.security.jgss.krb5.Krb5Util; +import sun.security.krb5.Credentials; +import sun.security.krb5.internal.ccache.CredentialsCache; + import com.sun.security.jgss.ExtendedGSSContext; import com.sun.security.jgss.InquireType; import com.sun.security.jgss.AuthorizationDataEntry; @@ -154,24 +165,36 @@ Map map = new HashMap<>(); Map shared = new HashMap<>(); + if (storeKey) { + map.put("storeKey", "true"); + } + if (pass != null) { - map.put("useFirstPass", "true"); - shared.put("javax.security.auth.login.name", user); - shared.put("javax.security.auth.login.password", pass); + krb5.initialize(out.s, new CallbackHandler() { + @Override + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException { + for (Callback cb: callbacks) { + if (cb instanceof NameCallback) { + ((NameCallback)cb).setName(user); + } else if (cb instanceof PasswordCallback) { + ((PasswordCallback)cb).setPassword(pass); + } + } + } + }, shared, map); } else { map.put("doNotPrompt", "true"); map.put("useTicketCache", "true"); if (user != null) { map.put("principal", user); } - } - if (storeKey) { - map.put("storeKey", "true"); + krb5.initialize(out.s, null, shared, map); } - krb5.initialize(out.s, null, shared, map); krb5.login(); krb5.commit(); + return out; } @@ -452,18 +475,21 @@ out = me.x.wrap(input, 0, input.length, p1); } System.out.println(printProp(p1)); + if ((x.getConfState() && privacy) != p1.getPrivacy()) { + throw new Exception("unexpected privacy status"); + } return out; } }, t); } - public byte[] unwrap(byte[] t, final boolean privacy) + public byte[] unwrap(byte[] t, final boolean privacyExpected) throws Exception { return doAs(new Action() { @Override public byte[] run(Context me, byte[] input) throws Exception { - System.out.printf("unwrap %s privacy from %s: ", privacy?"with":"without", me.name); - MessageProp p1 = new MessageProp(0, privacy); + System.out.printf("unwrap from %s", me.name); + MessageProp p1 = new MessageProp(0, true); byte[] bytes; if (usingStream) { ByteArrayOutputStream os = new ByteArrayOutputStream(); @@ -473,6 +499,9 @@ bytes = me.x.unwrap(input, 0, input.length, p1); } System.out.println(printProp(p1)); + if (p1.getPrivacy() != privacyExpected) { + throw new Exception("Unexpected privacy: " + p1.getPrivacy()); + } return bytes; } }, t); @@ -514,6 +543,10 @@ p1); } System.out.println(printProp(p1)); + if (p1.isUnseqToken() || p1.isOldToken() + || p1.isDuplicateToken() || p1.isGapToken()) { + throw new Exception("Wrong sequence number detected"); + } return null; } }, t); @@ -529,13 +562,27 @@ * @param s2 the receiver * @throws java.lang.Exception If anything goes wrong */ - static public void transmit(final String message, final Context s1, + static public void transmit(String message, final Context s1, + final Context s2) throws Exception { + transmit(message.getBytes(), s1, s2); + } + + /** + * Transmits a message from one Context to another. The sender wraps the + * message and sends it to the receiver. The receiver unwraps it, creates + * a MIC of the clear text and sends it back to the sender. The sender + * verifies the MIC against the message sent earlier. + * @param messageBytes the message + * @param s1 the sender + * @param s2 the receiver + * @throws java.lang.Exception If anything goes wrong + */ + static public void transmit(byte[] messageBytes, final Context s1, final Context s2) throws Exception { - final byte[] messageBytes = message.getBytes(); System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n", s1.name, s2.name); byte[] wrapped = s1.wrap(messageBytes, true); - byte[] unwrapped = s2.unwrap(wrapped, true); + byte[] unwrapped = s2.unwrap(wrapped, s2.x.getConfState()); if (!Arrays.equals(messageBytes, unwrapped)) { throw new Exception("wrap/unwrap mismatch"); } @@ -616,6 +663,32 @@ } /** + * Saves the tickets to a ccache file. + * + * @param file pathname of the ccache file + * @return true if created, false otherwise. + */ + public boolean ccache(String file) throws Exception { + Set tickets + = s.getPrivateCredentials(KerberosTicket.class); + if (tickets != null && !tickets.isEmpty()) { + CredentialsCache cc = null; + for (KerberosTicket t : tickets) { + Credentials cred = Krb5Util.ticketToCreds(t); + if (cc == null) { + cc = CredentialsCache.create(cred.getClient(), file); + } + cc.update(cred.toCCacheCreds()); + } + if (cc != null) { + cc.save(); + return true; + } + } + return false; + } + + /** * Handshake (security context establishment process) between two Contexts * @param c the initiator * @param s the acceptor diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/DiffSaltParams.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/DiffSaltParams.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/DiffSaltParams.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/DiffSaltParams.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8186831 + * @summary Kerberos ignores PA-DATA with a non-null s2kparams + * @compile -XDignore.symbol.file DiffSaltParams.java + * @run main/othervm -Dsun.security.krb5.debug=true -Dsun.net.spi.nameservice.provider.1=ns,mock DiffSaltParams + */ + +public class DiffSaltParams { + + public static void main(String[] args) throws Exception { + + OneKDC kdc = new OneKDC(null).writeJAASConf(); + kdc.addPrincipal("user1", "user1pass".toCharArray(), + "hello", new byte[]{0, 0, 1, 0}); + kdc.addPrincipal("user2", "user2pass".toCharArray(), + "hello", null); + kdc.addPrincipal("user3", "user3pass".toCharArray(), + null, new byte[]{0, 0, 1, 0}); + kdc.addPrincipal("user4", "user4pass".toCharArray()); + + Context.fromUserPass("user1", "user1pass".toCharArray(), true); + Context.fromUserPass("user2", "user2pass".toCharArray(), true); + Context.fromUserPass("user3", "user3pass".toCharArray(), true); + Context.fromUserPass("user4", "user4pass".toCharArray(), true); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Forwarded.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Forwarded.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Forwarded.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Forwarded.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031111 + * @summary fix krb5 caddr + * @compile -XDignore.symbol.file Forwarded.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Forwarded + */ + +import sun.security.jgss.GSSUtil; +import sun.security.krb5.internal.KDCOptions; +import sun.security.krb5.internal.KDCReqBody; +import sun.security.krb5.internal.TGSReq; + +public class Forwarded { + + public static void main(String[] args) throws Exception { + + new OneKDC(null).setOption(KDC.Option.CHECK_ADDRESSES, true); + + Context c; + c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.x().requestCredDeleg(true); + + c.take(new byte[0]); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/KDC.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/KDC.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/KDC.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/KDC.java 2020-01-15 20:05:09.000000000 +0000 @@ -27,19 +27,19 @@ import java.net.*; import java.io.*; import java.lang.reflect.Method; -import java.security.SecureRandom; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAmount; -import java.time.temporal.TemporalUnit; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; import java.util.concurrent.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; import sun.net.spi.nameservice.NameService; import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.CredentialsCache; +import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.crypto.KeyUsage; import sun.security.krb5.internal.ktab.KeyTab; import sun.security.util.DerInputStream; @@ -50,6 +50,11 @@ /** * A KDC server. + * + * Note: By setting the system property native.kdc.path to a native + * krb5 installation, this class starts a native KDC with the + * given realm and host. It can also add new principals and save keytabs. + * Other features might not be available. *

      * Features: *

        @@ -127,13 +132,21 @@ */ public class KDC { - // Under the hood. - public static final int DEFAULT_LIFETIME = 39600; public static final int DEFAULT_RENEWTIME = 86400; - // The random generator to generate random keys (including session keys) - private static SecureRandom secureRandom = new SecureRandom(); + // What etypes the KDC supports. Comma-separated strings. Null for all. + // Please note native KDCs might use different names. + private static final String SUPPORTED_ETYPES + = System.getProperty("kdc.supported.enctypes"); + + // The native KDC + private final NativeKdc nativeKdc; + + // The native KDC process + private Process kdcProc = null; + + // Under the hood. // Principal db. principal -> pass. A case-insensitive TreeMap is used // so that even if the client provides a name with different case, the KDC @@ -141,6 +154,25 @@ private TreeMap passwords = new TreeMap<> (String.CASE_INSENSITIVE_ORDER); + // Non default salts. Precisely, there should be different salts for + // different etypes, pretend they are the same at the moment. + private TreeMap salts = new TreeMap<> + (String.CASE_INSENSITIVE_ORDER); + + // Non default s2kparams for newer etypes. Precisely, there should be + // different s2kparams for different etypes, pretend they are the same + // at the moment. + private TreeMap s2kparamses = new TreeMap<> + (String.CASE_INSENSITIVE_ORDER); + + // Alias for referrals. + private TreeMap aliasReferrals = new TreeMap<> + (String.CASE_INSENSITIVE_ORDER); + + // Alias for local resolution. + private TreeMap alias2Principals = new TreeMap<> + (String.CASE_INSENSITIVE_ORDER); + // Realm name private String realm; // KDC @@ -213,6 +245,10 @@ * Sensitive accounts can never be delegated. */ SENSITIVE_ACCOUNTS, + /** + * If true, will check if TGS-REQ contains a non-null addresses field. + */ + CHECK_ADDRESSES, }; //static { @@ -223,7 +259,8 @@ * A standalone KDC server. */ public static void main(String[] args) throws Exception { - KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false); + int port = args.length > 0 ? Integer.parseInt(args[0]) : 0; + KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", port, false); kdc.addPrincipal("dummy", "bogus".toCharArray()); kdc.addPrincipal("foo", "bar".toCharArray()); kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE"); @@ -257,7 +294,8 @@ * @return the running KDC instance * @throws java.io.IOException for any socket creation error */ - public static KDC create(String realm, String kdc, int port, boolean asDaemon) throws IOException { + public static KDC create(String realm, String kdc, int port, + boolean asDaemon) throws IOException { return new KDC(realm, kdc, port, asDaemon); } @@ -297,26 +335,38 @@ */ public void writeKtab(String tab, boolean append, String... names) throws IOException, KrbException { - KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab); + KeyTab ktab = null; + if (nativeKdc == null) { + ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab); + } Iterable entries = (names.length != 0) ? Arrays.asList(names): passwords.keySet(); for (String name : entries) { - char[] pass = passwords.get(name); - int kvno = 0; - if (Character.isDigit(pass[pass.length-1])) { - kvno = pass[pass.length-1] - '0'; + if (name.indexOf('@') < 0) { + name = name + "@" + realm; } - PrincipalName pn = new PrincipalName(name, + if (nativeKdc == null) { + char[] pass = passwords.get(name); + int kvno = 0; + if (Character.isDigit(pass[pass.length - 1])) { + kvno = pass[pass.length - 1] - '0'; + } + PrincipalName pn = new PrincipalName(name, name.indexOf('/') < 0 ? - PrincipalName.KRB_NT_UNKNOWN : - PrincipalName.KRB_NT_SRV_HST); - ktab.addEntry(pn, + PrincipalName.KRB_NT_UNKNOWN : + PrincipalName.KRB_NT_SRV_HST); + ktab.addEntry(pn, getSalt(pn), pass, kvno, true); + } else { + nativeKdc.ktadd(name, tab); + } + } + if (nativeKdc == null) { + ktab.save(); } - ktab.save(); } /** @@ -362,10 +412,36 @@ * @param pass the password for the principal */ public void addPrincipal(String user, char[] pass) { + addPrincipal(user, pass, null, null); + } + + /** + * Adds a new principal to this realm with a given password. + * @param user the principal's name. For a service principal, use the + * form of host/f.q.d.n + * @param pass the password for the principal + * @param salt the salt, or null if a default value will be used + * @param s2kparams the s2kparams, or null if a default value will be used + */ + public void addPrincipal( + String user, char[] pass, String salt, byte[] s2kparams) { if (user.indexOf('@') < 0) { user = user + "@" + realm; } - passwords.put(user, pass); + if (nativeKdc != null) { + if (!user.equals("krbtgt/" + realm)) { + nativeKdc.addPrincipal(user, new String(pass)); + } + passwords.put(user, new char[0]); + } else { + passwords.put(user, pass); + if (salt != null) { + salts.put(user, salt); + } + if (s2kparams != null) { + s2kparamses.put(user, s2kparams); + } + } } /** @@ -461,12 +537,11 @@ */ public static void saveConfig(String file, KDC kdc, Object... more) throws IOException { - File f = new File(file); StringBuffer sb = new StringBuffer(); sb.append("[libdefaults]\ndefault_realm = "); sb.append(kdc.realm); sb.append("\n"); - for (Object o: more) { + for (Object o : more) { if (o instanceof String) { sb.append(o); sb.append("\n"); @@ -474,14 +549,12 @@ } sb.append("\n[realms]\n"); sb.append(kdc.realmLine()); - for (Object o: more) { + for (Object o : more) { if (o instanceof KDC) { - sb.append(((KDC)o).realmLine()); + sb.append(((KDC) o).realmLine()); } } - FileOutputStream fos = new FileOutputStream(f); - fos.write(sb.toString().getBytes()); - fos.close(); + Files.write(Paths.get(file), sb.toString().getBytes()); } /** @@ -492,6 +565,29 @@ return port; } + /** + * Register an alias name to be referred to a different KDC for + * resolution, according to RFC 6806. + * @param alias Alias name (i.e. user@REALM.COM). + * @param referredKDC KDC to which the alias is referred for resolution. + */ + public void registerAlias(String alias, KDC referredKDC) { + aliasReferrals.remove(alias); + aliasReferrals.put(alias, referredKDC); + } + + /** + * Register an alias to be resolved to a Principal Name locally, + * according to RFC 6806. + * @param alias Alias name (i.e. user@REALM.COM). + * @param user Principal Name to which the alias is resolved. + */ + public void registerAlias(String alias, String user) + throws RealmException { + alias2Principals.remove(alias); + alias2Principals.put(alias, new PrincipalName(user)); + } + // Private helper methods /** @@ -501,6 +597,7 @@ private KDC(String realm, String kdc) { this.realm = realm; this.kdc = kdc; + this.nativeKdc = null; } /** @@ -508,7 +605,9 @@ */ protected KDC(String realm, String kdc, int port, boolean asDaemon) throws IOException { - this(realm, kdc); + this.realm = realm; + this.kdc = kdc; + this.nativeKdc = NativeKdc.get(this); startServer(port, asDaemon); } /** @@ -517,8 +616,9 @@ */ private static char[] randomPassword() { char[] pass = new char[32]; + Random r = new Random(); for (int i=0; i<31; i++) - pass[i] = (char)secureRandom.nextInt(); + pass[i] = (char)('a' + r.nextInt(26)); // The last char cannot be a number, otherwise, keyForUser() // believes it's a sign of kvno pass[31] = 'Z'; @@ -580,6 +680,9 @@ if (p.getRealmString() == null) { pn = pn + "@" + getRealm(); } + if (salts.containsKey(pn)) { + return salts.get(pn); + } if (passwords.containsKey(pn)) { try { // Find the principal name with correct case. @@ -597,6 +700,29 @@ } /** + * Returns the s2kparams for the principal given the etype. + * @param p principal + * @param etype encryption type + * @return the s2kparams, might be null + */ + protected byte[] getParams(PrincipalName p, int etype) { + switch (etype) { + case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: + case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: + String pn = p.toString(); + if (p.getRealmString() == null) { + pn = pn + "@" + getRealm(); + } + if (s2kparamses.containsKey(pn)) { + return s2kparamses.get(pn); + } + return new byte[] {0, 0, 0x10, 0}; + default: + return null; + } + } + + /** * Returns the key for a given principal of the given encryption type * @param p the principal * @param etype the encryption type @@ -604,7 +730,7 @@ * @return the key * @throws sun.security.krb5.KrbException for unknown/unsupported etype */ - private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server) + EncryptionKey keyForUser(PrincipalName p, int etype, boolean server) throws KrbException { try { // Do not call EncryptionKey.acquireSecretKeys(), otherwise @@ -619,7 +745,7 @@ } } return new EncryptionKey(EncryptionKeyDotStringToKey( - getPassword(p, server), getSalt(p), null, etype), + getPassword(p, server), getSalt(p), getParams(p, etype), etype), etype, kvno); } catch (KrbException ke) { throw ke; @@ -668,17 +794,36 @@ " sends TGS-REQ for " + service + ", " + tgsReq.reqBody.kdcOptions); KDCReqBody body = tgsReq.reqBody; - int[] eTypes = KDCReqBodyDotEType(body); + int[] eTypes = filterSupported(KDCReqBodyDotEType(body)); + if (eTypes.length == 0) { + throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP); + } int e2 = eTypes[0]; // etype for outgoing session key int e3 = eTypes[0]; // etype for outgoing ticket - PAData[] pas = KDCReqDotPAData(tgsReq); + PAData[] pas = tgsReq.pAData; Ticket tkt = null; EncTicketPart etp = null; PrincipalName cname = null; boolean allowForwardable = true; + boolean isReferral = false; + if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) { + System.out.println(realm + "> verifying referral for " + + body.sname.getNameString()); + KDC referral = aliasReferrals.get(body.sname.getNameString()); + if (referral != null) { + service = new PrincipalName( + PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + + referral.getRealm(), PrincipalName.KRB_NT_SRV_INST, + this.getRealm()); + System.out.println(realm + "> referral to " + + referral.getRealm()); + isReferral = true; + } + } if (pas == null || pas.length == 0) { throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP); @@ -687,7 +832,6 @@ for (PAData pa: pas) { if (pa.getType() == Krb5.PA_TGS_REQ) { APReq apReq = new APReq(pa.getValue()); - EncryptedData ed = apReq.authenticator; tkt = apReq.ticket; int te = tkt.encPart.getEType(); EncryptionKey kkey = keyForUser(tkt.sname, te, true); @@ -705,13 +849,14 @@ PAForUserEnc p4u = new PAForUserEnc( new DerValue(pa.getValue()), null); forUserCName = p4u.name; - System.out.println(realm + "> presenting a PA_FOR_USER " + System.out.println(realm + "> See PA_FOR_USER " + " in the name of " + p4u.name); } } } if (forUserCName != null) { - List names = (List)options.get(Option.ALLOW_S4U2SELF); + List names = (List) + options.get(Option.ALLOW_S4U2SELF); if (!names.contains(cname.toString())) { // Mimic the normal KDC behavior. When a server is not // allowed to send S4U2self, do not send an error. @@ -732,11 +877,19 @@ EncryptionKey key = generateRandomKey(e2); // Check time, TODO + KerberosTime from = body.from; KerberosTime till = body.till; + if (from == null || from.isZero()) { + from = timeAfter(0); + } + KerberosTime rtime = body.rtime; if (till == null) { throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO } else if (till.isZero()) { - till = new KerberosTime(new Date().getTime() + 1000 * 3600 * 11); + till = timeAfter(DEFAULT_LIFETIME); + } + if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) { + rtime = timeAfter(DEFAULT_RENEWTIME); } boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1]; @@ -750,13 +903,19 @@ bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; } } + // We do not request for addresses for FORWARDED tickets + if (options.containsKey(Option.CHECK_ADDRESSES) + && body.kdcOptions.get(KDCOptions.FORWARDED) + && body.addresses != null) { + throw new KrbException(Krb5.KDC_ERR_BADOPTION); + } if (body.kdcOptions.get(KDCOptions.FORWARDED) || etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) { bFlags[Krb5.TKT_OPTS_FORWARDED] = true; } if (body.kdcOptions.get(KDCOptions.RENEWABLE)) { bFlags[Krb5.TKT_OPTS_RENEWABLE] = true; - //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7); + //renew = timeAfter(3600 * 24 * 7); } if (body.kdcOptions.get(KDCOptions.PROXIABLE)) { bFlags[Krb5.TKT_OPTS_PROXIABLE] = true; @@ -767,7 +926,8 @@ if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) { bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true; } - if (body.kdcOptions.get(KDCOptions.CNAME_IN_ADDL_TKT)) { + if (body.kdcOptions.get(KDCOptions.CNAME_IN_ADDL_TKT) && + !isReferral) { if (!options.containsKey(Option.ALLOW_S4U2PROXY)) { // Don't understand CNAME_IN_ADDL_TKT throw new KrbException(Krb5.KDC_ERR_BADOPTION); @@ -775,7 +935,8 @@ Map> map = (Map>) options.get(Option.ALLOW_S4U2PROXY); Ticket second = KDCReqBodyDotFirstAdditionalTicket(body); - EncryptionKey key2 = keyForUser(second.sname, second.encPart.getEType(), true); + EncryptionKey key2 = keyForUser( + second.sname, second.encPart.getEType(), true); byte[] bb = second.encPart.decrypt(key2, KeyUsage.KU_TICKET); DerInputStream derIn = new DerInputStream(bb); DerValue der = derIn.getDerValue(); @@ -807,19 +968,29 @@ } bFlags[Krb5.TKT_OPTS_INITIAL] = true; + KerberosTime renewTill = etp.renewTill; + if (renewTill != null && body.kdcOptions.get(KDCOptions.RENEW)) { + // till should never pass renewTill + if (till.greaterThan(renewTill)) { + till = renewTill; + } + if (System.getProperty("test.set.null.renew") != null) { + // Testing 8186576, see NullRenewUntil.java. + renewTill = null; + } + } + TicketFlags tFlags = new TicketFlags(bFlags); EncTicketPart enc = new EncTicketPart( tFlags, key, cname, new TransitedEncoding(1, new byte[0]), // TODO - new KerberosTime(new Date()), - body.from, - till, body.rtime, - body.addresses != null // always set caddr - ? body.addresses - : new HostAddresses( - new InetAddress[]{InetAddress.getLocalHost()}), + timeAfter(0), + from, + till, renewTill, + body.addresses != null ? body.addresses + : etp.caddr, null); EncryptionKey skey = keyForUser(service, e3, true); if (skey == null) { @@ -833,23 +1004,22 @@ ); EncTGSRepPart enc_part = new EncTGSRepPart( key, - new LastReq(new LastReqEntry[]{ - new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000)) + new LastReq(new LastReqEntry[] { + new LastReqEntry(0, timeAfter(-10)) }), body.getNonce(), // TODO: detect replay - new KerberosTime(new Date().getTime() + 1000 * 3600 * 24), + timeAfter(3600 * 24), // Next 5 and last MUST be same with ticket tFlags, - new KerberosTime(new Date()), - body.from, - till, body.rtime, + timeAfter(0), + from, + till, renewTill, service, - body.addresses != null // always set caddr - ? body.addresses - : new HostAddresses( - new InetAddress[]{InetAddress.getLocalHost()}) + body.addresses, + null ); - EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY); + EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), + KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY); TGSRep tgsRep = new TGSRep(null, cname, t, @@ -870,7 +1040,7 @@ + " " +ke.returnCodeMessage()); if (kerr == null) { kerr = new KRBError(null, null, null, - new KerberosTime(new Date()), + timeAfter(0), 0, ke.returnCode(), body.cname, @@ -890,6 +1060,7 @@ */ protected byte[] processAsReq(byte[] in) throws Exception { ASReq asReq = new ASReq(in); + byte[] asReqbytes = asReq.asn1Encode(); int[] eTypes = null; List outPAs = new ArrayList<>(); @@ -906,9 +1077,29 @@ KDCReqBody body = asReq.reqBody; - eTypes = KDCReqBodyDotEType(body); + eTypes = filterSupported(KDCReqBodyDotEType(body)); + if (eTypes.length == 0) { + throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP); + } int eType = eTypes[0]; + if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) { + PrincipalName principal = alias2Principals.get( + body.cname.getNameString()); + if (principal != null) { + body.cname = principal; + } else { + KDC referral = aliasReferrals.get(body.cname.getNameString()); + if (referral != null) { + body.cname = new PrincipalName( + PrincipalName.TGS_DEFAULT_SRV_NAME, + PrincipalName.KRB_NT_SRV_INST, + referral.getRealm()); + throw new KrbException(Krb5.KRB_ERR_WRONG_REALM); + } + } + } + EncryptionKey ckey = keyForUser(body.cname, eType, false); EncryptionKey skey = keyForUser(service, eType, true); @@ -936,8 +1127,12 @@ // Session key EncryptionKey key = generateRandomKey(eType); // Check time, TODO + KerberosTime from = body.from; KerberosTime till = body.till; KerberosTime rtime = body.rtime; + if (from == null || from.isZero()) { + from = timeAfter(0); + } if (till == null) { throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO } else if (till.isZero()) { @@ -963,7 +1158,8 @@ if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) { List sensitives = (List) options.get(Option.SENSITIVE_ACCOUNTS); - if (sensitives != null && sensitives.contains(body.cname.toString())) { + if (sensitives != null + && sensitives.contains(body.cname.toString())) { // Cannot make FORWARDABLE } else { bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; @@ -971,7 +1167,7 @@ } if (body.kdcOptions.get(KDCOptions.RENEWABLE)) { bFlags[Krb5.TKT_OPTS_RENEWABLE] = true; - //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7); + //renew = timeAfter(3600 * 24 * 7); } if (body.kdcOptions.get(KDCOptions.PROXIABLE)) { bFlags[Krb5.TKT_OPTS_PROXIABLE] = true; @@ -993,7 +1189,8 @@ pas2 = new DerValue[] { new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()), - new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()), + new DerValue(new ETypeInfo2( + 1, realm, new byte[]{1}).asn1Encode()), }; pas = new DerValue[] { new DerValue(new ETypeInfo(1, null).asn1Encode()), @@ -1003,7 +1200,8 @@ break; case 2: // we still reject non-null s2kparams and prefer E2 over E pas2 = new DerValue[] { - new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()), + new DerValue(new ETypeInfo2( + 1, realm, new byte[]{1}).asn1Encode()), new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()), }; @@ -1054,7 +1252,7 @@ epas[i], epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ? null : getSalt(body.cname), - null).asn1Encode()); + getParams(body.cname, epas[i])).asn1Encode()); } boolean allOld = true; for (int i: eTypes) { @@ -1088,21 +1286,47 @@ outPAs.add(new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray())); } - PAData[] inPAs = KDCReqDotPAData(asReq); - if (inPAs == null || inPAs.length == 0) { + PAData[] inPAs = asReq.pAData; + List enc_outPAs = new ArrayList<>(); + + byte[] paEncTimestamp = null; + if (inPAs != null) { + for (PAData inPA : inPAs) { + if (inPA.getType() == Krb5.PA_ENC_TIMESTAMP) { + paEncTimestamp = inPA.getValue(); + } + } + } + + if (paEncTimestamp == null) { Object preauth = options.get(Option.PREAUTH_REQUIRED); if (preauth == null || preauth.equals(Boolean.TRUE)) { throw new KrbException(Krb5.KDC_ERR_PREAUTH_REQUIRED); } } else { + EncryptionKey pakey = null; try { - EncryptedData data = newEncryptedData(new DerValue(inPAs[0].getValue())); - EncryptionKey pakey = keyForUser(body.cname, data.getEType(), false); + EncryptedData data = newEncryptedData( + new DerValue(paEncTimestamp)); + pakey = keyForUser(body.cname, data.getEType(), false); data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS); } catch (Exception e) { - throw new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED); + KrbException ke = new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED); + ke.initCause(e); + throw ke; } bFlags[Krb5.TKT_OPTS_PRE_AUTHENT] = true; + for (PAData pa : inPAs) { + if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) { + Checksum ckSum = new Checksum( + Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128, + asReqbytes, ckey, KeyUsage.KU_AS_REQ); + enc_outPAs.add(new PAData(Krb5.PA_REQ_ENC_PA_REP, + ckSum.asn1Encode())); + bFlags[Krb5.TKT_OPTS_ENC_PA_REP] = true; + break; + } + } } TicketFlags tFlags = new TicketFlags(bFlags); @@ -1111,8 +1335,8 @@ key, body.cname, new TransitedEncoding(1, new byte[0]), - new KerberosTime(new Date()), - body.from, + timeAfter(0), + from, till, rtime, body.addresses, null); @@ -1123,19 +1347,21 @@ EncASRepPart enc_part = new EncASRepPart( key, new LastReq(new LastReqEntry[]{ - new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000)) + new LastReqEntry(0, timeAfter(-10)) }), body.getNonce(), // TODO: detect replay? - new KerberosTime(new Date().getTime() + 1000 * 3600 * 24), + timeAfter(3600 * 24), // Next 5 and last MUST be same with ticket tFlags, - new KerberosTime(new Date()), - body.from, + timeAfter(0), + from, till, rtime, service, - body.addresses + body.addresses, + enc_outPAs.toArray(new PAData[enc_outPAs.size()]) ); - EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_AS_REP_PART); + EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), + KeyUsage.KU_ENC_AS_REP_PART); ASRep asRep = new ASRep( outPAs.toArray(new PAData[outPAs.size()]), body.cname, @@ -1180,8 +1406,10 @@ if (kerr == null) { if (ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED || ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) { + outPAs.add(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0])); + } + if (outPAs.size() > 0) { DerOutputStream bytes = new DerOutputStream(); - bytes.write(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]).asn1Encode()); for (PAData p: outPAs) { bytes.write(p.asn1Encode()); } @@ -1190,7 +1418,7 @@ eData = temp.toByteArray(); } kerr = new KRBError(null, null, null, - new KerberosTime(new Date()), + timeAfter(0), 0, ke.returnCode(), body.cname, @@ -1268,6 +1496,35 @@ throw new KrbException("Illegal duration format " + s); } + private int[] filterSupported(int[] input) { + int count = 0; + for (int i = 0; i < input.length; i++) { + if (!EType.isSupported(input[i])) { + continue; + } + if (SUPPORTED_ETYPES != null) { + boolean supported = false; + for (String se : SUPPORTED_ETYPES.split(",")) { + if (Config.getType(se) == input[i]) { + supported = true; + break; + } + } + if (!supported) { + continue; + } + } + if (count != i) { + input[count] = input[i]; + } + count++; + } + if (count != input.length) { + input = Arrays.copyOf(input, count); + } + return input; + } + /** * Generates a line for a KDC to put inside [realms] of krb5.conf * @return REALM.NAME = { kdc = host:port etc } @@ -1292,6 +1549,20 @@ * @throws java.io.IOException for any communication error */ protected void startServer(int port, boolean asDaemon) throws IOException { + if (nativeKdc != null) { + startNativeServer(port, asDaemon); + } else { + startJavaServer(port, asDaemon); + } + } + + private void startNativeServer(int port, boolean asDaemon) throws IOException { + nativeKdc.prepare(); + nativeKdc.init(); + kdcProc = nativeKdc.kdc(); + } + + private void startJavaServer(int port, boolean asDaemon) throws IOException { if (port > 0) { u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1")); t1 = new ServerSocket(port); @@ -1384,19 +1655,37 @@ } } + public void kinit(String user, String ccache) throws Exception { + if (user.indexOf('@') < 0) { + user = user + "@" + realm; + } + if (nativeKdc != null) { + nativeKdc.kinit(user, ccache); + } else { + Context.fromUserPass(user, passwords.get(user), false) + .ccache(ccache); + } + } + boolean isReady() { return udpConsumerReady && tcpConsumerReady && dispatcherReady; } public void terminate() { - try { - thread1.stop(); - thread2.stop(); - thread3.stop(); - u1.close(); - t1.close(); - } catch (Exception e) { - // OK + if (nativeKdc != null) { + System.out.println("Killing kdc..."); + kdcProc.destroyForcibly(); + System.out.println("Done"); + } else { + try { + thread1.stop(); + thread2.stop(); + thread3.stop(); + u1.close(); + t1.close(); + } catch (Exception e) { + // OK + } } } @@ -1551,8 +1840,270 @@ } } + /** + * A native KDC using the binaries in nativePath. Attention: + * this is using binaries, not an existing KDC instance. + * An implementation of this takes care of configuration, + * principal db managing and KDC startup. + */ + static abstract class NativeKdc { + + protected Map env; + protected String nativePath; + protected String base; + protected String realm; + protected int port; + + NativeKdc(String nativePath, KDC kdc) { + if (kdc.port == 0) { + kdc.port = 8000 + new java.util.Random().nextInt(10000); + } + this.nativePath = nativePath; + this.realm = kdc.realm; + this.port = kdc.port; + this.base = Paths.get("" + port).toAbsolutePath().toString(); + } + + // Add a new principal + abstract void addPrincipal(String user, String pass); + // Add a keytab entry + abstract void ktadd(String user, String ktab); + // Initialize KDC + abstract void init(); + // Start kdc + abstract Process kdc(); + // Configuration + abstract void prepare(); + // Fill ccache + abstract void kinit(String user, String ccache); + + static NativeKdc get(KDC kdc) { + String prop = System.getProperty("native.kdc.path"); + if (prop == null) { + return null; + } else if (Files.exists(Paths.get(prop, "sbin/krb5kdc"))) { + return new MIT(true, prop, kdc); + } else if (Files.exists(Paths.get(prop, "kdc/krb5kdc"))) { + return new MIT(false, prop, kdc); + } else if (Files.exists(Paths.get(prop, "libexec/kdc"))) { + return new Heimdal(prop, kdc); + } else { + throw new IllegalArgumentException("Strange " + prop); + } + } + + Process run(boolean wait, String... cmd) { + try { + System.out.println("Running " + cmd2str(env, cmd)); + ProcessBuilder pb = new ProcessBuilder(); + pb.inheritIO(); + pb.environment().putAll(env); + Process p = pb.command(cmd).start(); + if (wait) { + if (p.waitFor() < 0) { + throw new RuntimeException("exit code is not null"); + } + return null; + } else { + return p; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private String cmd2str(Map env, String... cmd) { + return env.entrySet().stream().map(e -> e.getKey()+"="+e.getValue()) + .collect(Collectors.joining(" ")) + " " + + Stream.of(cmd).collect(Collectors.joining(" ")); + } + } + + // Heimdal KDC. Build your own and run "make install" to nativePath. + static class Heimdal extends NativeKdc { + + Heimdal(String nativePath, KDC kdc) { + super(nativePath, kdc); + Map environment = new HashMap<>(); + environment.put("KRB5_CONFIG", base + "/krb5.conf"); + environment.put("KRB5_TRACE", "/dev/stderr"); + environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib"); + environment.put("LD_LIBRARY_PATH", nativePath + "/lib"); + this.env = Collections.unmodifiableMap(environment); + } + + @Override + public void addPrincipal(String user, String pass) { + run(true, nativePath + "/bin/kadmin", "-l", "-r", realm, + "add", "-p", pass, "--use-defaults", user); + } + + @Override + public void ktadd(String user, String ktab) { + run(true, nativePath + "/bin/kadmin", "-l", "-r", realm, + "ext_keytab", "-k", ktab, user); + } + + @Override + public void init() { + run(true, nativePath + "/bin/kadmin", "-l", "-r", realm, + "init", "--realm-max-ticket-life=1day", + "--realm-max-renewable-life=1month", realm); + } + + @Override + public Process kdc() { + return run(false, nativePath + "/libexec/kdc", + "--addresses=127.0.0.1", "-P", "" + port); + } + + @Override + public void prepare() { + try { + Files.createDirectory(Paths.get(base)); + Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList( + "[libdefaults]", + "default_realm = " + realm, + "default_keytab_name = FILE:" + base + "/krb5.keytab", + "forwardable = true", + "dns_lookup_kdc = no", + "dns_lookup_realm = no", + "dns_canonicalize_hostname = false", + "\n[realms]", + realm + " = {", + " kdc = localhost:" + port, + "}", + "\n[kdc]", + "db-dir = " + base, + "database = {", + " label = {", + " dbname = " + base + "/current-db", + " realm = " + realm, + " mkey_file = " + base + "/mkey.file", + " acl_file = " + base + "/heimdal.acl", + " log_file = " + base + "/current.log", + " }", + "}", + SUPPORTED_ETYPES == null ? "" + : ("\n[kadmin]\ndefault_keys = " + + (SUPPORTED_ETYPES + ",") + .replaceAll(",", ":pw-salt ")), + "\n[logging]", + "kdc = 0-/FILE:" + base + "/messages.log", + "krb5 = 0-/FILE:" + base + "/messages.log", + "default = 0-/FILE:" + base + "/messages.log" + )); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + void kinit(String user, String ccache) { + String tmpName = base + "/" + user + "." + + System.identityHashCode(this) + ".keytab"; + ktadd(user, tmpName); + run(true, nativePath + "/bin/kinit", + "-f", "-t", tmpName, "-c", ccache, user); + } + } + + // MIT krb5 KDC. Make your own exploded (install == false), or + // "make install" into nativePath (install == true). + static class MIT extends NativeKdc { + + private boolean install; // "make install" or "make" + + MIT(boolean install, String nativePath, KDC kdc) { + super(nativePath, kdc); + this.install = install; + Map environment = new HashMap<>(); + environment.put("KRB5_KDC_PROFILE", base + "/kdc.conf"); + environment.put("KRB5_CONFIG", base + "/krb5.conf"); + environment.put("KRB5_TRACE", "/dev/stderr"); + environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib"); + environment.put("LD_LIBRARY_PATH", nativePath + "/lib"); + this.env = Collections.unmodifiableMap(environment); + } + + @Override + public void addPrincipal(String user, String pass) { + run(true, nativePath + + (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local", + "-q", "addprinc -pw " + pass + " " + user); + } + + @Override + public void ktadd(String user, String ktab) { + run(true, nativePath + + (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local", + "-q", "ktadd -k " + ktab + " -norandkey " + user); + } + + @Override + public void init() { + run(true, nativePath + + (install ? "/sbin/" : "/kadmin/dbutil/") + "kdb5_util", + "create", "-s", "-W", "-P", "olala"); + } + + @Override + public Process kdc() { + return run(false, nativePath + + (install ? "/sbin/" : "/kdc/") + "krb5kdc", + "-n"); + } + + @Override + public void prepare() { + try { + Files.createDirectory(Paths.get(base)); + Files.write(Paths.get(base + "/kdc.conf"), Arrays.asList( + "[kdcdefaults]", + "\n[realms]", + realm + "= {", + " kdc_listen = " + this.port, + " kdc_tcp_listen = " + this.port, + " database_name = " + base + "/principal", + " key_stash_file = " + base + "/.k5.ATHENA.MIT.EDU", + SUPPORTED_ETYPES == null ? "" + : (" supported_enctypes = " + + (SUPPORTED_ETYPES + ",") + .replaceAll(",", ":normal ")), + "}" + )); + Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList( + "[libdefaults]", + "default_realm = " + realm, + "default_keytab_name = FILE:" + base + "/krb5.keytab", + "forwardable = true", + "dns_lookup_kdc = no", + "dns_lookup_realm = no", + "dns_canonicalize_hostname = false", + "\n[realms]", + realm + " = {", + " kdc = localhost:" + port, + "}", + "\n[logging]", + "kdc = FILE:" + base + "/krb5kdc.log" + )); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + void kinit(String user, String ccache) { + String tmpName = base + "/" + user + "." + + System.identityHashCode(this) + ".keytab"; + ktadd(user, tmpName); + run(true, nativePath + + (install ? "/bin/" : "/clients/kinit/") + "kinit", + "-f", "-t", tmpName, "-c", ccache, user); + } + } + // Calling private methods thru reflections - private static final Field getPADataField; private static final Field getEType; private static final Constructor ctorEncryptedData; private static final Method stringToKey; @@ -1562,8 +2113,6 @@ try { ctorEncryptedData = EncryptedData.class.getDeclaredConstructor(DerValue.class); ctorEncryptedData.setAccessible(true); - getPADataField = KDCReq.class.getDeclaredField("pAData"); - getPADataField.setAccessible(true); getEType = KDCReqBody.class.getDeclaredField("eType"); getEType.setAccessible(true); stringToKey = EncryptionKey.class.getDeclaredMethod( @@ -1584,13 +2133,6 @@ } catch (Exception e) { throw new AssertionError(e); } - } - private static PAData[] KDCReqDotPAData(KDCReq req) { - try { - return (PAData[])getPADataField.get(req); - } catch (Exception e) { - throw new AssertionError(e); - } } private static int[] KDCReqBodyDotEType(KDCReqBody body) { try { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/LifeTimeInSeconds.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/LifeTimeInSeconds.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/LifeTimeInSeconds.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/LifeTimeInSeconds.java 2020-01-15 20:05:09.000000000 +0000 @@ -40,7 +40,7 @@ int time = cred.getRemainingLifetime(); int time2 = cred.getRemainingInitLifetime(null); // The test KDC issues a TGT with a default lifetime of 11 hours - int elevenhrs = 11*3600; + int elevenhrs = KDC.DEFAULT_LIFETIME; if (time > elevenhrs+60 || time < elevenhrs-60) { throw new Exception("getRemainingLifetime returns wrong value."); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/NullRenewUntil.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/NullRenewUntil.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/NullRenewUntil.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/NullRenewUntil.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8186576 + * @summary KerberosTicket does not properly handle renewable tickets + * at the end of their lifetime + * @library /lib/testlibrary/ + * @compile -XDignore.symbol.file NullRenewUntil.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock -Dtest.set.null.renew NullRenewUntil + */ + +import jdk.testlibrary.Asserts; +import sun.security.krb5.Config; + +import javax.security.auth.kerberos.KerberosTicket; + +public class NullRenewUntil { + + public static void main(String[] args) throws Exception { + + OneKDC kdc = new OneKDC(null); + + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "ticket_lifetime = 10s", + "renew_lifetime = 11s"); + Config.refresh(); + + KerberosTicket ticket = Context + .fromUserPass(OneKDC.USER, OneKDC.PASS, false).s() + .getPrivateCredentials(KerberosTicket.class).iterator().next(); + + System.out.println(ticket); + Asserts.assertTrue(ticket.getRenewTill() != null, ticket.toString()); + + Thread.sleep(2000); + + ticket.refresh(); + System.out.println(ticket); + Asserts.assertTrue(ticket.getRenewTill() == null, ticket.toString()); + + Thread.sleep(2000); + ticket.refresh(); + System.out.println(ticket); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/ReferralsTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/ReferralsTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/ReferralsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/ReferralsTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8215032 + * @run main/othervm/timeout=120 -Dsun.security.krb5.debug=true ReferralsTest + * @summary Test Kerberos cross-realm referrals (RFC 6806) + */ + +import java.io.File; +import java.security.Principal; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.security.auth.kerberos.KerberosTicket; +import javax.security.auth.Subject; + +import org.ietf.jgss.GSSName; + +import sun.security.jgss.GSSUtil; +import sun.security.krb5.PrincipalName; + +public class ReferralsTest { + private static final boolean DEBUG = true; + private static final String krbConfigName = "krb5-localkdc.conf"; + private static final String realmKDC1 = "RABBIT.HOLE"; + private static final String realmKDC2 = "DEV.RABBIT.HOLE"; + private static final char[] password = "123qwe@Z".toCharArray(); + + // Names + private static final String clientName = "test"; + private static final String serviceName = "http" + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + + "server.dev.rabbit.hole"; + + // Alias + private static final String clientAlias = clientName + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1; + + // Names + realms + private static final String clientKDC1Name = clientAlias.replaceAll( + PrincipalName.NAME_REALM_SEPARATOR_STR, "\\\\" + + PrincipalName.NAME_REALM_SEPARATOR_STR) + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1; + private static final String clientKDC2Name = clientName + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2; + private static final String serviceKDC2Name = serviceName + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2; + + public static void main(String[] args) throws Exception { + try { + initializeKDCs(); + testSubjectCredentials(); + testDelegated(); + } finally { + cleanup(); + } + } + + private static void initializeKDCs() throws Exception { + KDC kdc1 = KDC.create(realmKDC1, "localhost", 0, true); + kdc1.addPrincipalRandKey(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1); + kdc1.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1 + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2, + password); + kdc1.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2, + password); + + KDC kdc2 = KDC.create(realmKDC2, "localhost", 0, true); + kdc2.addPrincipalRandKey(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2); + kdc2.addPrincipal(clientKDC2Name, password); + kdc2.addPrincipal(serviceName, password); + kdc2.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1, + password); + kdc2.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2 + + PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1, + password); + + kdc1.registerAlias(clientAlias, kdc2); + kdc1.registerAlias(serviceName, kdc2); + kdc2.registerAlias(clientAlias, clientKDC2Name); + + Map> mapKDC2 = new HashMap<>(); + mapKDC2.put(serviceName + "@" + realmKDC2, Arrays.asList( + new String[]{serviceName + "@" + realmKDC2})); + kdc2.setOption(KDC.Option.ALLOW_S4U2PROXY, mapKDC2); + + KDC.saveConfig(krbConfigName, kdc1, kdc2, + "forwardable=true"); + System.setProperty("java.security.krb5.conf", krbConfigName); + } + + private static void cleanup() { + File f = new File(krbConfigName); + if (f.exists()) { + f.delete(); + } + } + + /* + * The client subject (whose principal is + * test@RABBIT.HOLE@RABBIT.HOLE) will obtain a TGT after + * realm referral and name canonicalization (TGT cname + * will be test@DEV.RABBIT.HOLE). With this TGT, the client will request + * a TGS for service http/server.dev.rabbit.hole@RABBIT.HOLE. After + * realm referral, a http/server.dev.rabbit.hole@DEV.RABBIT.HOLE TGS + * will be obtained. + * + * Assert that we get the proper TGT and TGS tickets, and that they are + * associated to the client subject. + * + * Assert that if we request a TGS for the same service again (based on the + * original service name), we don't get a new one but the previous, + * already in the subject credentials. + */ + private static void testSubjectCredentials() throws Exception { + Subject clientSubject = new Subject(); + Context clientContext = Context.fromUserPass(clientSubject, + clientKDC1Name, password, false); + + Set clientPrincipals = clientSubject.getPrincipals(); + if (clientPrincipals.size() != 1) { + throw new Exception("Only one client subject principal expected"); + } + Principal clientPrincipal = clientPrincipals.iterator().next(); + if (DEBUG) { + System.out.println("Client subject principal: " + + clientPrincipal.getName()); + } + if (!clientPrincipal.getName().equals(clientKDC1Name)) { + throw new Exception("Unexpected client subject principal."); + } + + clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); + clientContext.take(new byte[0]); + Set clientTickets = + clientSubject.getPrivateCredentials(KerberosTicket.class); + boolean tgtFound = false; + boolean tgsFound = false; + for (KerberosTicket clientTicket : clientTickets) { + String cname = clientTicket.getClient().getName(); + String sname = clientTicket.getServer().getName(); + if (cname.equals(clientKDC2Name)) { + if (sname.equals(PrincipalName.TGS_DEFAULT_SRV_NAME + + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + + realmKDC2 + PrincipalName.NAME_REALM_SEPARATOR_STR + + realmKDC2)) { + tgtFound = true; + } else if (sname.equals(serviceKDC2Name)) { + tgsFound = true; + } + } + if (DEBUG) { + System.out.println("Client subject KerberosTicket:"); + System.out.println(clientTicket); + } + } + if (!tgtFound || !tgsFound) { + throw new Exception("client subject tickets (TGT/TGS) not found."); + } + int numOfTickets = clientTickets.size(); + clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); + clientContext.take(new byte[0]); + clientContext.status(); + int newNumOfTickets = + clientSubject.getPrivateCredentials(KerberosTicket.class).size(); + if (DEBUG) { + System.out.println("client subject number of tickets: " + + numOfTickets); + System.out.println("client subject new number of tickets: " + + newNumOfTickets); + } + if (numOfTickets != newNumOfTickets) { + throw new Exception("Useless client subject TGS request because" + + " TGS was not found in private credentials."); + } + } + + /* + * The server (http/server.dev.rabbit.hole@DEV.RABBIT.HOLE) + * will authenticate on itself on behalf of the client + * (test@DEV.RABBIT.HOLE). Cross-realm referrals will occur + * when requesting different TGTs and TGSs (including the + * request for delegated credentials). + */ + private static void testDelegated() throws Exception { + Context c = Context.fromUserPass(clientKDC2Name, + password, false); + c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); + Context s = Context.fromUserPass(serviceKDC2Name, + password, true); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + Context.handshake(c, s); + Context delegatedContext = s.delegated(); + delegatedContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); + delegatedContext.x().requestMutualAuth(false); + Context s2 = Context.fromUserPass(serviceKDC2Name, + password, true); + s2.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + + // Test authentication + Context.handshake(delegatedContext, s2); + if (!delegatedContext.x().isEstablished() || !s2.x().isEstablished()) { + throw new Exception("Delegated authentication failed"); + } + + // Test identities + GSSName contextInitiatorName = delegatedContext.x().getSrcName(); + GSSName contextAcceptorName = delegatedContext.x().getTargName(); + if (DEBUG) { + System.out.println("Context initiator: " + contextInitiatorName); + System.out.println("Context acceptor: " + contextAcceptorName); + } + if (!contextInitiatorName.toString().equals(clientKDC2Name) || + !contextAcceptorName.toString().equals(serviceName)) { + throw new Exception("Unexpected initiator or acceptor names"); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Renewal.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Renewal.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Renewal.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Renewal.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8044500 + * @summary Add kinit options and krb5.conf flags that allow users to + * obtain renewable tickets and specify ticket lifetimes + * @library ../../../../java/security/testlibrary/ + * @compile -XDignore.symbol.file Renewal.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renewal + */ + +import sun.security.jgss.GSSUtil; +import sun.security.krb5.Config; +import sun.security.krb5.internal.ccache.Credentials; +import sun.security.krb5.internal.ccache.FileCredentialsCache; + +import javax.security.auth.kerberos.KerberosTicket; +import java.util.Date; +import java.util.Random; +import java.util.Set; + +// The basic krb5 test skeleton you can copy from +public class Renewal { + + static OneKDC kdc; + static String clazz = "sun.security.krb5.internal.tools.Kinit"; + + public static void main(String[] args) throws Exception { + + kdc = new OneKDC(null); + kdc.writeJAASConf(); + kdc.setOption(KDC.Option.PREAUTH_REQUIRED, false); + + checkLogin(null, null, KDC.DEFAULT_LIFETIME, -1); + checkLogin("1h", null, 3600, -1); + checkLogin(null, "2d", KDC.DEFAULT_LIFETIME, 86400*2); + checkLogin("1h", "10h", 3600, 36000); + // When rtime is before till, use till as rtime + checkLogin("10h", "1h", 36000, 36000); + + try { + Class.forName(clazz); + } catch (ClassNotFoundException cnfe) { + return; + } + + checkKinit(null, null, null, null, KDC.DEFAULT_LIFETIME, -1); + checkKinit("1h", "10h", null, null, 3600, 36000); + checkKinit(null, null, "30m", "5h", 1800, 18000); + checkKinit("1h", "10h", "30m", "5h", 1800, 18000); + + checkKinitRenew(); + } + + static int count = 0; + + static void checkKinit( + String s1, // ticket_lifetime in krb5.conf, null if none + String s2, // renew_lifetime in krb5.conf, null if none + String c1, // -l on kinit, null if none + String c2, // -r on kinit, null if none + int t1, int t2 // expected lifetimes, -1 of unexpected + ) throws Exception { + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + s1 != null ? ("ticket_lifetime = " + s1) : "", + s2 != null ? ("renew_lifetime = " + s2) : ""); + Proc p = Proc.create(clazz); + if (c1 != null) { + p.args("-l", c1); + } + if (c2 != null) { + p.args("-r", c2); + } + count++; + p.args(OneKDC.USER, new String(OneKDC.PASS)) + .inheritIO() + .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) + .env("KRB5CCNAME", "ccache" + count) + .start(); + if (p.waitFor() != 0) { + throw new Exception(); + } + FileCredentialsCache fcc = + FileCredentialsCache.acquireInstance(null, "ccache" + count); + Credentials cred = fcc.getDefaultCreds(); + checkRough(cred.getEndTime().toDate(), t1); + if (cred.getRenewTill() == null) { + checkRough(null, t2); + } else { + checkRough(cred.getRenewTill().toDate(), t2); + } + } + + static void checkKinitRenew() throws Exception { + Proc p = Proc.create(clazz) + .args("-R") + .inheritIO() + .prop("sun.net.spi.nameservice.provider.1", "ns,mock") + .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) + .env("KRB5CCNAME", "ccache" + count) + .start(); + if (p.waitFor() != 0) { + throw new Exception(); + } + } + + static void checkLogin( + String s1, // ticket_lifetime in krb5.conf, null if none + String s2, // renew_lifetime in krb5.conf, null if none + int t1, int t2 // expected lifetimes, -1 of unexpected + ) throws Exception { + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + s1 != null ? ("ticket_lifetime = " + s1) : "", + s2 != null ? ("renew_lifetime = " + s2) : ""); + Config.refresh(); + + Context c; + c = Context.fromJAAS("client"); + + Set tickets = + c.s().getPrivateCredentials(KerberosTicket.class); + if (tickets.size() != 1) { + throw new Exception(); + } + KerberosTicket ticket = tickets.iterator().next(); + + checkRough(ticket.getEndTime(), t1); + checkRough(ticket.getRenewTill(), t2); + } + + static void checkRough(Date t, int duration) throws Exception { + Date now = new Date(); + if (t == null && duration == -1) { + return; + } + long change = (t.getTime() - System.currentTimeMillis()) / 1000; + if (change > duration + 20 || change < duration - 20) { + throw new Exception(t + " is not " + duration); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Renew.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Renew.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/Renew.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/Renew.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8058290 + * @summary JAAS Krb5LoginModule has suspect ticket-renewal logic, + * relies on clockskew grace + * @compile -XDignore.symbol.file Renew.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 1 + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 2 + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 3 + */ + +import sun.security.krb5.Config; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Date; +import javax.security.auth.kerberos.KerberosTicket; + +public class Renew { + + public static void main(String[] args) throws Exception { + + // Three test cases: + // 1. renewTGT=false + // 2. renewTGT=true with a short life time, renew will happen + // 3. renewTGT=true with a long life time, renew won't happen + int test = Integer.parseInt(args[0]); + + OneKDC k = new OneKDC(null); + KDC.saveConfig(OneKDC.KRB5_CONF, k, + "renew_lifetime = 1d", + "ticket_lifetime = " + (test == 2? "10s": "8h")); + Config.refresh(); + k.writeJAASConf(); + + // KDC would save ccache in a file + System.setProperty("test.kdc.save.ccache", "cache.here"); + + Files.write(Paths.get(OneKDC.JAAS_CONF), Arrays.asList( + "first {", + " com.sun.security.auth.module.Krb5LoginModule required;", + "};", + "second {", + " com.sun.security.auth.module.Krb5LoginModule required", + " doNotPrompt=true", + " renewTGT=" + (test != 1), + " useTicketCache=true", + " ticketCache=cache.here;", + "};" + )); + + Context c; + + // The first login uses username and password + c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + Date d1 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime(); + + // 6s is longer than half of 10s + Thread.sleep(6000); + + // The second login uses the cache + c = Context.fromJAAS("second"); + Date d2 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime(); + + if (test == 2) { + if (d1.equals(d2)) { + throw new Exception("Ticket not renewed"); + } + } else { + if (!d1.equals(d2)) { + throw new Exception("Ticket renewed"); + } + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/SaslGSS.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/SaslGSS.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/auto/SaslGSS.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/auto/SaslGSS.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8012082 8019267 - * @summary SASL: auth-conf negotiated, but unencrypted data is accepted, - * reset to unencrypt - * @compile -XDignore.symbol.file SaslGSS.java - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock SaslGSS - */ - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.sasl.AuthorizeCallback; -import javax.security.sasl.RealmCallback; -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslServer; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.HashMap; -import java.util.Locale; -import java.util.logging.ConsoleHandler; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.ietf.jgss.*; -import sun.security.jgss.GSSUtil; - -public class SaslGSS { - - public static void main(String[] args) throws Exception { - - String name = "host." + OneKDC.REALM.toLowerCase(Locale.US); - - new OneKDC(null).writeJAASConf(); - System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); - - // Client in JGSS so that it can control wrap privacy mode - GSSManager m = GSSManager.getInstance(); - GSSContext sc = m.createContext( - m.createName(OneKDC.SERVER, GSSUtil.NT_GSS_KRB5_PRINCIPAL), - GSSUtil.GSS_KRB5_MECH_OID, - null, - GSSContext.DEFAULT_LIFETIME); - sc.requestMutualAuth(false); - - // Server in SASL - final HashMap props = new HashMap(); - props.put(Sasl.QOP, "auth-conf"); - SaslServer ss = Sasl.createSaslServer("GSSAPI", "server", - name, props, - new CallbackHandler() { - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException { - for (Callback cb : callbacks) { - if (cb instanceof RealmCallback) { - ((RealmCallback) cb).setText(OneKDC.REALM); - } else if (cb instanceof AuthorizeCallback) { - ((AuthorizeCallback) cb).setAuthorized(true); - } - } - } - }); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - PrintStream oldErr = System.err; - System.setErr(new PrintStream(bout)); - - Logger.getLogger("javax.security.sasl").setLevel(Level.ALL); - Handler h = new ConsoleHandler(); - h.setLevel(Level.ALL); - Logger.getLogger("javax.security.sasl").addHandler(h); - - byte[] token = new byte[0]; - - try { - // Handshake - token = sc.initSecContext(token, 0, token.length); - token = ss.evaluateResponse(token); - token = sc.unwrap(token, 0, token.length, new MessageProp(0, false)); - token[0] = (byte)(((token[0] & 4) != 0) ? 4 : 2); - token = sc.wrap(token, 0, token.length, new MessageProp(0, false)); - ss.evaluateResponse(token); - } finally { - System.setErr(oldErr); - } - - // Talk - // 1. Client sends a auth-int message - byte[] hello = "hello".getBytes(); - MessageProp qop = new MessageProp(0, false); - token = sc.wrap(hello, 0, hello.length, qop); - // 2. Server accepts it anyway - ss.unwrap(token, 0, token.length); - // 3. Server sends a message - token = ss.wrap(hello, 0, hello.length); - // 4. Client accepts, should be auth-conf - sc.unwrap(token, 0, token.length, qop); - if (!qop.getPrivacy()) { - throw new Exception(); - } - - for (String s: bout.toString().split("\\n")) { - if (s.contains("KRB5SRV04") && s.contains("NULL")) { - return; - } - } - System.out.println("======================="); - System.out.println(bout.toString()); - System.out.println("======================="); - throw new Exception("Haven't seen KRB5SRV04 with NULL"); - } -} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/config/Duration.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/config/Duration.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/krb5/config/Duration.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/krb5/config/Duration.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8044500 + * @summary Add kinit options and krb5.conf flags that allow users to + * obtain renewable tickets and specify ticket lifetimes + * @compile -XDignore.symbol.file Duration.java + * @run main Duration + */ +import sun.security.krb5.Config; +import sun.security.krb5.KrbException; + +public class Duration { + public static void main(String[] args) throws Exception { + check("123", 123); + check("1:1", 3660); + check("1:1:1", 3661); + check("1d", 86400); + check("1h", 3600); + check("1h1m", 3660); + check("1h 1m", 3660); + check("1d 1h 1m 1s", 90061); + check("1d1h1m1s", 90061); + + check("", -1); + check("abc", -1); + check("1ms", -1); + check("1d1d", -1); + check("1h1d", -1); + check("x1h", -1); + check("1h x 1m", -1); + check(":", -1); + check("1:60", -1); + check("1:1:1:1", -1); + check("1:1:1:", -1); + } + + static void check(String s, int ex) throws Exception { + System.out.print("\u001b[1;37;41m" +s + " " + ex); + System.out.print("\u001b[m\n"); + try { + int result = Config.duration(s); + if (result != ex) throw new Exception("for " + s + " is " + result); + } catch (KrbException ke) { + ke.printStackTrace(); + if (ex != -1) throw new Exception(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/lib/cacerts/VerifyCACerts.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/lib/cacerts/VerifyCACerts.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/lib/cacerts/VerifyCACerts.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/lib/cacerts/VerifyCACerts.java 2020-01-15 20:05:09.000000000 +0000 @@ -26,7 +26,7 @@ * @test * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779 * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 - * 8223499 + * 8223499 8232019 8233223 * @summary Check root CA entries in cacerts file */ import java.io.File; @@ -50,7 +50,7 @@ + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 88; + private static final int COUNT = 93; // map of cert alias to SHA-256 fingerprint @SuppressWarnings("serial") @@ -233,6 +233,16 @@ "DD:69:36:FE:21:F8:F0:77:C1:23:A1:A5:21:C1:22:24:F7:22:55:B7:3E:03:A7:26:06:93:E8:A2:4B:0F:A3:89"); put("globalsignrootcar6 [jdk]", "2C:AB:EA:FE:37:D0:6C:A2:2A:BA:73:91:C0:03:3D:25:98:29:52:C4:53:64:73:49:76:3A:3A:B5:AD:6C:CF:69"); + put("luxtrustglobalroot2ca [jdk]", + "54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5"); + put("amazonrootca1 [jdk]", + "8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E"); + put("amazonrootca2 [jdk]", + "1B:A5:B2:AA:8C:65:40:1A:82:96:01:18:F8:0B:EC:4F:62:30:4D:83:CE:C4:71:3A:19:C3:9C:01:1E:A4:6D:B4"); + put("amazonrootca3 [jdk]", + "18:CE:6C:FE:7B:F1:4E:60:B2:E3:47:B8:DF:E8:68:CB:31:D0:2E:BB:3A:DA:27:15:69:F5:03:43:B4:6D:B3:A4"); + put("amazonrootca4 [jdk]", + "E3:5D:28:41:9E:D0:20:25:CF:A6:90:38:CD:62:39:62:45:8D:A5:C6:95:FB:DE:A3:C2:2B:0B:FB:25:89:70:92"); } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/pkcs12/MixedcaseAlias.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/pkcs12/MixedcaseAlias.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/pkcs12/MixedcaseAlias.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/pkcs12/MixedcaseAlias.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8173956 + * @summary KeyStore regression due to default keystore being changed to PKCS12 + */ + +import java.io.*; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +/** + * Test that a PKCS12 keystore entry with mixed-case alias can be retrieved. + */ +public class MixedcaseAlias { + private static final String DIR = System.getProperty("test.src", "."); + private static final String CERT = DIR + "/trusted.pem"; + private static final String ALIAS = "Mixed-case Alias"; + + public static void main(String[] ignored) throws Exception { + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(null, null); + + keystore.setCertificateEntry(ALIAS, loadCertificate(CERT)); + KeyStore.Entry entry = keystore.getEntry(ALIAS, null); + + if (entry == null) { + throw new Exception( + "Error retrieving keystore entry using a mixed-case alias"); + } + + System.out.println("OK"); + } + + private static Certificate loadCertificate(String certFile) + throws Exception { + X509Certificate cert = null; + try (FileInputStream certStream = new FileInputStream(certFile)) { + CertificateFactory factory = + CertificateFactory.getInstance("X.509"); + return factory.generateCertificate(certStream); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/provider/DSA/TestAlgParameterGenerator.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/provider/DSA/TestAlgParameterGenerator.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/provider/DSA/TestAlgParameterGenerator.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/provider/DSA/TestAlgParameterGenerator.java 2020-01-15 20:05:09.000000000 +0000 @@ -23,56 +23,59 @@ /* * @test - * @bug 7044060 8181048 + * @bug 7044060 8055351 8181048 * @summary verify that DSA parameter generation works - * @run main/othervm/timeout=300 TestAlgParameterGenerator + * @run main/timeout=600 TestAlgParameterGenerator */ -import java.security.*; -import java.security.spec.*; -import java.security.interfaces.*; + +import java.security.AlgorithmParameterGenerator; +import java.security.AlgorithmParameters; +import java.security.spec.DSAGenParameterSpec; +import java.security.spec.DSAParameterSpec; public class TestAlgParameterGenerator { private static void checkParamStrength(AlgorithmParameters param, - int strength) throws Exception { + int strength) throws Exception { String algo = param.getAlgorithm(); if (!algo.equalsIgnoreCase("DSA")) { - throw new Exception("Unexpected type of parameters: " + algo); + throw new RuntimeException("Unexpected type of parameters: " + algo); } DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class); int valueL = spec.getP().bitLength(); if (strength != valueL) { System.out.println("Expected " + strength + " but actual " + valueL); - throw new Exception("Wrong P strength"); + throw new RuntimeException("Wrong P strength"); } } + private static void checkParamStrength(AlgorithmParameters param, - DSAGenParameterSpec genParam) - throws Exception { + DSAGenParameterSpec genParam) + throws Exception { String algo = param.getAlgorithm(); if (!algo.equalsIgnoreCase("DSA")) { - throw new Exception("Unexpected type of parameters: " + algo); + throw new RuntimeException("Unexpected type of parameters: " + algo); } DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class); int valueL = spec.getP().bitLength(); int strength = genParam.getPrimePLength(); if (strength != valueL) { System.out.println("P: Expected " + strength + " but actual " + valueL); - throw new Exception("Wrong P strength"); + throw new RuntimeException("Wrong P strength"); } int valueN = spec.getQ().bitLength(); strength = genParam.getSubprimeQLength(); if (strength != valueN) { System.out.println("Q: Expected " + strength + " but actual " + valueN); - throw new Exception("Wrong Q strength"); + throw new RuntimeException("Wrong Q strength"); } } public static void main(String[] args) throws Exception { - AlgorithmParameterGenerator apg = - AlgorithmParameterGenerator.getInstance("DSA", "SUN"); - + AlgorithmParameterGenerator apg + = AlgorithmParameterGenerator.getInstance("DSA", "SUN"); long start, stop; + // make sure no-init still works start = System.currentTimeMillis(); AlgorithmParameters param = apg.generateParameters(); @@ -80,9 +83,8 @@ System.out.println("Time: " + (stop - start) + " ms."); // make sure the old model works - int[] strengths = { 512, 768, 1024 }; - for (int i = 0; i < strengths.length; i++) { - int sizeP = strengths[i]; + int[] strengths = {512, 768, 1024}; + for (int sizeP : strengths) { System.out.println("Generating " + sizeP + "-bit DSA Parameters"); start = System.currentTimeMillis(); apg.init(sizeP); @@ -93,18 +95,17 @@ } // now the newer model - DSAGenParameterSpec spec1 = new DSAGenParameterSpec(1024, 160); - DSAGenParameterSpec spec2 = new DSAGenParameterSpec(2048, 224); - DSAGenParameterSpec spec3 = new DSAGenParameterSpec(2048, 256); - //DSAGenParameterSpec spec4 = new DSAGenParameterSpec(3072, 256); DSAGenParameterSpec[] specSet = { - spec1, spec2, spec3//, spec4 + new DSAGenParameterSpec(1024, 160), + new DSAGenParameterSpec(2048, 224), + new DSAGenParameterSpec(2048, 256) + // no support for prime size 3072 + // ,new DSAGenParameterSpec(3072, 256) }; - for (int i = 0; i < specSet.length; i++) { - DSAGenParameterSpec genParam = specSet[i]; - System.out.println("Generating (" + genParam.getPrimePLength() + - ", " + genParam.getSubprimeQLength() + - ") DSA Parameters"); + + for (DSAGenParameterSpec genParam : specSet) { + System.out.println("Generating (" + genParam.getPrimePLength() + + ", " + genParam.getSubprimeQLength() + ") DSA Parameters"); start = System.currentTimeMillis(); apg.init(genParam, null); param = apg.generateParameters(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/provider/DSA/TestMaxLengthDER.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/provider/DSA/TestMaxLengthDER.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/provider/DSA/TestMaxLengthDER.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/provider/DSA/TestMaxLengthDER.java 2020-01-15 20:05:09.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8183591 + * @summary Test decoding of DER length fields containing Integer.MAX_VALUE + * @run main TestMaxLengthDER + */ + +import java.io.*; +import java.math.*; +import java.security.*; +import java.security.spec.*; + +public class TestMaxLengthDER { + + public static void main(String[] args) throws Exception { + + String message = "Message"; + Signature sig = Signature.getInstance("SHA256withDSA"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); + SecureRandom rnd = new SecureRandom(); + rnd.setSeed(1); + kpg.initialize(2048, rnd); + KeyPair kp = kpg.generateKeyPair(); + sig.initSign(kp.getPrivate()); + sig.update(message.getBytes()); + byte[] sigData = sig.sign(); + + // Set the length of the second integer to Integer.MAX_VALUE + // First copy all the signature data to the correct location + int lengthPos = sigData[3] + 5; + byte[] modifiedSigData = new byte[sigData.length + 4]; + System.arraycopy(sigData, 0, modifiedSigData, 0, lengthPos); + System.arraycopy(sigData, lengthPos + 1, modifiedSigData, + lengthPos + 5, sigData.length - (lengthPos + 1)); + + // Increase the length (in bytes) of the sequence to account for + // the larger length field + modifiedSigData[1] += 4; + + // Modify the length field + modifiedSigData[lengthPos] = (byte) 0x84; + modifiedSigData[lengthPos + 1] = (byte) 0x7F; + modifiedSigData[lengthPos + 2] = (byte) 0xFF; + modifiedSigData[lengthPos + 3] = (byte) 0xFF; + modifiedSigData[lengthPos + 4] = (byte) 0xFF; + + sig.initVerify(kp.getPublic()); + sig.update(message.getBytes()); + + try { + sig.verify(modifiedSigData); + throw new RuntimeException("No exception on misencoded signature"); + } catch (SignatureException ex) { + if (ex.getCause() instanceof EOFException) { + // this is expected + } else { + throw ex; + } + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -21,27 +21,31 @@ * questions. */ -/* - * This test is run using PostThruProxy.sh - */ - import java.io.*; import java.net.*; import java.security.KeyStore; import javax.net.*; import javax.net.ssl.*; -import java.security.cert.*; + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; /* - * This test case is written to test the https POST through a proxy. - * There is no proxy authentication done. - * - * PostThruProxy.java -- includes a simple server that serves - * http POST method requests in secure channel, and a client - * that makes https POST request through a proxy. + * @test + * @bug 4423074 + * @summary This test case is written to test the https POST through a proxy. + * There is no proxy authentication done. It includes a simple server + * that serves http POST method requests in secure channel, and a client + * that makes https POST request through a proxy. + * @library /lib/testlibrary + * @compile OriginServer.java ProxyTunnelServer.java + * @run main/othervm PostThruProxy */ - public class PostThruProxy { + + private static final String TEST_SRC = System.getProperty("test.src", "."); + private static final int TIMEOUT = 30000; + /* * Where do we find the keystores? */ @@ -76,14 +80,10 @@ /* * Main method to create the server and client */ - public static void main(String args[]) throws Exception - { - String keyFilename = - args[1] + "/" + pathToStores + - "/" + keyStoreFile; - String trustFilename = - args[1] + "/" + pathToStores + - "/" + trustStoreFile; + public static void main(String args[]) throws Exception { + String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile; + String trustFilename = TEST_SRC + "/" + pathToStores + "/" + + trustStoreFile; System.setProperty("javax.net.ssl.keyStore", keyFilename); System.setProperty("javax.net.ssl.keyStorePassword", passwd); @@ -95,10 +95,9 @@ * setup the server */ try { - ServerSocketFactory ssf = - PostThruProxy.getServerSocketFactory(useSSL); + ServerSocketFactory ssf = getServerSocketFactory(useSSL); ServerSocket ss = ssf.createServerSocket(serverPort); - ss.setSoTimeout(30000); // 30 seconds + ss.setSoTimeout(TIMEOUT); // 30 seconds serverPort = ss.getLocalPort(); new TestServer(ss); } catch (Exception e) { @@ -108,35 +107,29 @@ } // trigger the client try { - doClientSide(args[0]); + doClientSide(); } catch (Exception e) { System.out.println("Client side failed: " + e.getMessage()); throw e; - } + } } private static ServerSocketFactory getServerSocketFactory (boolean useSSL) throws Exception { if (useSSL) { - SSLServerSocketFactory ssf = null; // set up key manager to do server authentication - SSLContext ctx; - KeyManagerFactory kmf; - KeyStore ks; + SSLContext ctx = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + KeyStore ks = KeyStore.getInstance("JKS"); char[] passphrase = passwd.toCharArray(); - ctx = SSLContext.getInstance("TLS"); - kmf = KeyManagerFactory.getInstance("SunX509"); - ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(System.getProperty( "javax.net.ssl.keyStore")), passphrase); kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); - ssf = ctx.getServerSocketFactory(); - return ssf; + return ctx.getServerSocketFactory(); } else { return ServerSocketFactory.getDefault(); } @@ -147,7 +140,7 @@ */ static String postMsg = "Testing HTTP post on a https server"; - static void doClientSide(String hostname) throws Exception { + static void doClientSide() throws Exception { HostnameVerifier reservedHV = HttpsURLConnection.getDefaultHostnameVerifier(); try { @@ -162,10 +155,12 @@ */ HttpsURLConnection.setDefaultHostnameVerifier( new NameVerifier()); - URL url = new URL("https://" + hostname+ ":" + serverPort); + URL url = new URL("https://" + getHostname() +":" + serverPort); Proxy p = new Proxy(Proxy.Type.HTTP, pAddr); HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p); + https.setConnectTimeout(TIMEOUT); + https.setReadTimeout(TIMEOUT); https.setDoOutput(true); https.setRequestMethod("POST"); PrintStream ps = null; @@ -190,6 +185,9 @@ if (ps != null) ps.close(); throw e; + } catch (SocketTimeoutException e) { + System.out.println("Client can not get response in time: " + + e.getMessage()); } } finally { HttpsURLConnection.setDefaultHostnameVerifier(reservedHV); @@ -210,4 +208,13 @@ pserver.start(); return new InetSocketAddress("localhost", pserver.getPort()); } + + private static String getHostname() { + try { + OutputAnalyzer oa = ProcessTools.executeCommand("hostname"); + return oa.getOutput().trim(); + } catch (Throwable e) { + throw new RuntimeException("Get hostname failed.", e); + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please 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 4423074 -# @summary Need to rebase all the duplicated classes from Merlin - -HOSTNAME=`uname -n` -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin | AIX ) - PS=":" - FS="/" - ;; - CYGWIN* ) - PS=";" - FS="/" - ;; - Windows* ) - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . \ - ${TESTSRC}${FS}OriginServer.java \ - ${TESTSRC}${FS}ProxyTunnelServer.java \ - ${TESTSRC}${FS}PostThruProxy.java -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} PostThruProxy ${HOSTNAME} ${TESTSRC} -exit diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -21,28 +21,31 @@ * questions. */ -/* - * This test is run through PostThruProxyWithAuth.sh - */ - import java.io.*; import java.net.*; import java.security.KeyStore; import javax.net.*; import javax.net.ssl.*; -import java.security.cert.*; + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; /* - * This test case is written to test the https POST through a proxy - * with proxy authentication. - * - * PostThruProxyWithAuth.java -- includes a simple server that serves - * http POST method requests in secure channel, and a client - * that makes https POST request through a proxy. + * @test + * @bug 4423074 + * @summary This test case is written to test the https POST through a proxy + * with proxy authentication. It includes a simple server that serves + * http POST method requests in secure channel, and a client that + * makes https POST request through a proxy. + * @library /lib/testlibrary + * @compile OriginServer.java ProxyTunnelServer.java + * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth */ - public class PostThruProxyWithAuth { + private static final String TEST_SRC = System.getProperty("test.src", "."); + private static final int TIMEOUT = 30000; + /* * Where do we find the keystores? */ @@ -78,14 +81,10 @@ /* * Main method to create the server and client */ - public static void main(String args[]) throws Exception - { - String keyFilename = - args[1] + "/" + pathToStores + - "/" + keyStoreFile; - String trustFilename = - args[1] + "/" + pathToStores + - "/" + trustStoreFile; + public static void main(String args[]) throws Exception { + String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile; + String trustFilename = TEST_SRC + "/" + pathToStores + "/" + + trustStoreFile; System.setProperty("javax.net.ssl.keyStore", keyFilename); System.setProperty("javax.net.ssl.keyStorePassword", passwd); @@ -97,10 +96,9 @@ * setup the server */ try { - ServerSocketFactory ssf = - PostThruProxyWithAuth.getServerSocketFactory(useSSL); + ServerSocketFactory ssf = getServerSocketFactory(useSSL); ServerSocket ss = ssf.createServerSocket(serverPort); - ss.setSoTimeout(30000); // 30 seconds + ss.setSoTimeout(TIMEOUT); // 30 seconds serverPort = ss.getLocalPort(); new TestServer(ss); } catch (Exception e) { @@ -110,7 +108,7 @@ } // trigger the client try { - doClientSide(args[0]); + doClientSide(); } catch (Exception e) { System.out.println("Client side failed: " + e.getMessage()); @@ -121,24 +119,18 @@ private static ServerSocketFactory getServerSocketFactory (boolean useSSL) throws Exception { if (useSSL) { - SSLServerSocketFactory ssf = null; // set up key manager to do server authentication - SSLContext ctx; - KeyManagerFactory kmf; - KeyStore ks; + SSLContext ctx = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + KeyStore ks = KeyStore.getInstance("JKS"); char[] passphrase = passwd.toCharArray(); - ctx = SSLContext.getInstance("TLS"); - kmf = KeyManagerFactory.getInstance("SunX509"); - ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(System.getProperty( "javax.net.ssl.keyStore")), passphrase); kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); - ssf = ctx.getServerSocketFactory(); - return ssf; + return ctx.getServerSocketFactory(); } else { return ServerSocketFactory.getDefault(); } @@ -149,7 +141,7 @@ */ static String postMsg = "Testing HTTP post on a https server"; - static void doClientSide(String hostname) throws Exception { + static void doClientSide() throws Exception { /* * setup up a proxy */ @@ -161,10 +153,12 @@ */ HttpsURLConnection.setDefaultHostnameVerifier( new NameVerifier()); - URL url = new URL("https://" + hostname + ":" + serverPort); + URL url = new URL("https://" + getHostname() + ":" + serverPort); Proxy p = new Proxy(Proxy.Type.HTTP, pAddr); HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p); + https.setConnectTimeout(TIMEOUT); + https.setReadTimeout(TIMEOUT); https.setDoOutput(true); https.setRequestMethod("POST"); PrintStream ps = null; @@ -188,6 +182,9 @@ if (ps != null) ps.close(); throw e; + } catch (SocketTimeoutException e) { + System.out.println("Client can not get response in time: " + + e.getMessage()); } } @@ -221,4 +218,13 @@ "test123".toCharArray()); } } + + private static String getHostname() { + try { + OutputAnalyzer oa = ProcessTools.executeCommand("hostname"); + return oa.getOutput().trim(); + } catch (Throwable e) { + throw new RuntimeException("Get hostname failed.", e); + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please 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 4423074 -# @summary Need to rebase all the duplicated classes from Merlin - -HOSTNAME=`uname -n` -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin | AIX ) - PS=":" - FS="/" - ;; - CYGWIN* ) - PS=";" - FS="/" - ;; - Windows* ) - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}${FS}OriginServer.java \ - ${TESTSRC}${FS}ProxyTunnelServer.java \ - ${TESTSRC}${FS}PostThruProxyWithAuth.java -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \ - -Djdk.http.auth.tunneling.disabledSchemes= \ - PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC} -exit diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -32,13 +32,14 @@ import java.io.*; import java.net.*; -import javax.net.ssl.*; import javax.net.ServerSocketFactory; import sun.net.www.*; import java.util.Base64; public class ProxyTunnelServer extends Thread { + private static final int TIMEOUT = 30000; + private static ServerSocket ss = null; /* * holds the registered user's username and password @@ -64,8 +65,9 @@ public ProxyTunnelServer() throws IOException { if (ss == null) { - ss = (ServerSocket) ServerSocketFactory.getDefault(). - createServerSocket(0); + ss = (ServerSocket) ServerSocketFactory.getDefault() + .createServerSocket(0); + ss.setSoTimeout(TIMEOUT); } } @@ -86,6 +88,9 @@ try { clientSocket = ss.accept(); processRequests(); + } catch (SocketTimeoutException e) { + System.out.println( + "Proxy can not get response in time: " + e.getMessage()); } catch (Exception e) { System.out.println("Proxy Failed: " + e); e.printStackTrace(); @@ -188,8 +193,8 @@ serverToClient.start(); System.out.println("Proxy: Started tunneling......."); - clientToServer.join(); - serverToClient.join(); + clientToServer.join(TIMEOUT); + serverToClient.join(TIMEOUT); System.out.println("Proxy: Finished tunneling........"); clientToServer.close(); @@ -219,13 +224,11 @@ int BUFFER_SIZE = 400; byte[] buf = new byte[BUFFER_SIZE]; int bytesRead = 0; - int count = 0; // keep track of the amount of data transfer try { while ((bytesRead = input.read(buf)) >= 0) { output.write(buf, 0, bytesRead); output.flush(); - count += bytesRead; } } catch (IOException e) { /* @@ -236,7 +239,7 @@ } } - public void close() { + private void close() { try { if (!sockIn.isClosed()) sockIn.close(); @@ -275,7 +278,7 @@ serverPort = Integer.parseInt(connectInfo.substring(endi+1)); } catch (Exception e) { throw new IOException("Proxy recieved a request: " - + connectStr); + + connectStr, e); } serverInetAddr = InetAddress.getByName(serverName); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/concise_jarsigner.sh openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/concise_jarsigner.sh --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/concise_jarsigner.sh 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/concise_jarsigner.sh 2020-01-15 20:05:09.000000000 +0000 @@ -22,7 +22,7 @@ # # @test -# @bug 6802846 8172529 +# @bug 6802846 8172529 8227758 # @summary jarsigner needs enhanced cert validation(options) # # @run shell/timeout=240 concise_jarsigner.sh @@ -207,15 +207,11 @@ $JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain [ $? = 0 ] || exit $LINENO -# if ca2 is removed, -certchain still work because altchain is a self-signed entry and -# it is trusted by jarsigner +# if ca2 is removed and cert is imported, -certchain won't work because this certificate +# entry is not trusted # save ca2.cert for easy replay $KT -exportcert -file ca2.cert -alias ca2 $KT -delete -alias ca2 -$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain -[ $? = 0 ] || exit $LINENO - -# if cert is imported, -certchain won't work because this certificate entry is not trusted $KT -importcert -file certchain -alias altchain -noprompt $JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain [ $? = 4 ] || exit $LINENO @@ -228,8 +224,8 @@ # ========================================================== $KT -genkeypair -alias ee -dname CN=ee -$KT -genkeypair -alias caone -dname CN=caone -$KT -genkeypair -alias catwo -dname CN=catwo +$KT -genkeypair -alias caone -dname CN=caone -ext bc:c +$KT -genkeypair -alias catwo -dname CN=catwo -ext bc:c $KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert $KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/ec.sh openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/ec.sh --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/ec.sh 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/ec.sh 2020-01-15 20:05:09.000000000 +0000 @@ -53,7 +53,7 @@ echo A > A $JAR cvf $JFILE A -$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11 +$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 -ext bc:c || exit 11 $KT -alias a -dname CN=a -keyalg ec -genkey || exit 11 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111 diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/EntriesOrder.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/EntriesOrder.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/EntriesOrder.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/EntriesOrder.java 2020-01-15 20:05:09.000000000 +0000 @@ -25,6 +25,9 @@ * @test * @bug 8031572 * @summary jarsigner -verify exits with 0 when a jar file is not properly signed + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main EntriesOrder */ import java.io.FileInputStream; @@ -39,6 +42,8 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import jdk.testlibrary.IOUtils; + public class EntriesOrder { public static void main(String[] args) throws Exception { @@ -106,7 +111,7 @@ Enumeration jes = jf.entries(); while (jes.hasMoreElements()) { JarEntry je = jes.nextElement(); - sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true); + IOUtils.readFully(jf.getInputStream(je)); Certificate[] certs = je.getCertificates(); if (certs != null && certs.length > 0) { cc++; @@ -138,7 +143,7 @@ while (true) { JarEntry je = jis.getNextJarEntry(); if (je == null) break; - sun.misc.IOUtils.readFully(jis, -1, true); + IOUtils.readFully(jis); Certificate[] certs = je.getCertificates(); if (certs != null && certs.length > 0) { cc++; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/onlymanifest.sh openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/onlymanifest.sh --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/onlymanifest.sh 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/onlymanifest.sh 2020-01-15 20:05:09.000000000 +0000 @@ -57,7 +57,7 @@ echo "Key: Value" > manifest $JAR cvfm $JFILE manifest -$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1 +$KT -alias ca -dname CN=ca -genkey -validity 300 -ext bc:c || exit 1 $KT -alias a -dname CN=a -genkey -validity 300 || exit 2 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3 $JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4 diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/TimestampCheck.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/TimestampCheck.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/TimestampCheck.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/TimestampCheck.java 2020-01-15 20:05:09.000000000 +0000 @@ -743,7 +743,7 @@ try (JarFile jf = new JarFile(file)) { JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA"); try (InputStream is = jf.getInputStream(je)) { - byte[] content = IOUtils.readFully(is, -1, true); + byte[] content = IOUtils.readAllBytes(is); PKCS7 p7 = new PKCS7(content); SignerInfo[] si = p7.getSignerInfos(); if (si == null || si.length == 0) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/TsacertOptionTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/TsacertOptionTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/TsacertOptionTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/TsacertOptionTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -87,6 +87,7 @@ "-storepass", PASSWORD, "-keypass", PASSWORD, "-dname", "CN=CA", + "-ext", "bc:c", "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); ProcessTools.executeCommand(KEYTOOL, "-genkey", diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/Warning.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/Warning.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/Warning.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/Warning.java 2020-01-15 20:05:09.000000000 +0000 @@ -42,7 +42,7 @@ Files.deleteIfExists(Paths.get("ks")); - newCert("ca", "-validity 365000"); + newCert("ca", "-validity 365000", "-ext bc:c"); recreateJar(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ // create a certificate whose signer certificate's // ExtendedKeyUsage extension doesn't allow code signing // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ // create a certificate whose signer certificate's KeyUsage extension // doesn't allow code signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ // create a certificate whose signer certificate's // NetscapeCertType extension doesn't allow code signing // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ // Root CA is not checked at all. If the intermediate CA has // BasicConstraints extension set to true, it will be valid. // Otherwise, chain validation will fail. - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(CA2_KEY_ALIAS); issueCert(CA2_KEY_ALIAS, "-ext", diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( KEY_ALIAS, diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ // create a jar file that contains one class file JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); // create first expired certificate // whose ExtendedKeyUsage extension does not allow code signing diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * 24 * 60 * 60 * 1000L); // create key pair - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert(KEY_ALIAS, "-validity", Integer.toString(VALIDITY)); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ Utils.createFiles(FIRST_FILE); JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); // create first key pair for signing createAlias(FIRST_KEY_ALIAS); diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create certificate that will be valid only tomorrow - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/util/DerValue/BadValue.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/util/DerValue/BadValue.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/util/DerValue/BadValue.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/util/DerValue/BadValue.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,43 +35,48 @@ public static void main(String[] args) throws Exception { - // Test IOUtils.readFully + // Test IOUtils. // We have 4 bytes InputStream in = new ByteArrayInputStream(new byte[10]); - byte[] bs = IOUtils.readFully(in, 4, true); + byte[] bs = IOUtils.readExactlyNBytes(in, 4); if (bs.length != 4 || in.available() != 6) { throw new Exception("First read error"); } // But only 6 left - bs = IOUtils.readFully(in, 10, false); + bs = IOUtils.readNBytes(in, 10); if (bs.length != 6 || in.available() != 0) { throw new Exception("Second read error"); } - // MAX read as much as it can + // MAX length results in exception in = new ByteArrayInputStream(new byte[10]); - bs = IOUtils.readFully(in, Integer.MAX_VALUE, true); - if (bs.length != 10 || in.available() != 0) { - throw new Exception("Second read error"); + try { + bs = IOUtils.readExactlyNBytes(in, Integer.MAX_VALUE); + throw new Exception("No exception on MAX_VALUE length"); + } catch (EOFException ex) { + // this is expected } - // MAX ignore readAll + // -1 length results in exception in = new ByteArrayInputStream(new byte[10]); - bs = IOUtils.readFully(in, Integer.MAX_VALUE, false); - if (bs.length != 10 || in.available() != 0) { - throw new Exception("Second read error"); + try { + bs = IOUtils.readExactlyNBytes(in, -1); + throw new Exception("No exception on -1 length"); + } catch (IOException ex) { + // this is expected } + // 20>10, readAll means failure in = new ByteArrayInputStream(new byte[10]); try { - bs = IOUtils.readFully(in, 20, true); - throw new Exception("Third read error"); + bs = IOUtils.readExactlyNBytes(in, 20); + throw new Exception("No exception on EOF"); } catch (EOFException e) { // OK } int bignum = 10 * 1024 * 1024; - bs = IOUtils.readFully(new SuperSlowStream(bignum), -1, true); + bs = IOUtils.readExactlyNBytes(new SuperSlowStream(bignum), bignum); if (bs.length != bignum) { - throw new Exception("Fourth read error"); + throw new Exception("Read returned small array"); } // Test DerValue diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/validator/EndEntityExtensionCheck.java openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/validator/EndEntityExtensionCheck.java --- openjdk-8-8u232-b09/=unpacked-tar7=/test/sun/security/validator/EndEntityExtensionCheck.java 2019-10-10 03:21:07.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/test/sun/security/validator/EndEntityExtensionCheck.java 2020-01-15 20:05:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @bug 8076117 * @summary EndEntityChecker should not process custom extensions * after PKIX validation + * @run main/othervm -Djdk.security.allowNonCaAnchor EndEntityExtensionCheck */ import java.io.ByteArrayInputStream; diff -Nru openjdk-8-8u232-b09/=unpacked-tar7=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar7=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar7=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar7=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar8=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar8=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar8=/.hg_archival.txt 2019-08-12 20:24:23.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar8=/.hg_archival.txt 2020-01-13 04:57:57.000000000 +0000 @@ -1,5 +1,4 @@ repo: 9a66ca7c79fab293c1bb0534e0d208c7e4f58b01 -node: 735048c9f2d6835b76a436beffd29565f28a2a36 +node: b2b31daec366e7725872dd53dd800cbc9ada70c9 branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar8=/.hgtags openjdk-8-8u242-b08/=unpacked-tar8=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar8=/.hgtags 2019-08-12 20:24:23.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar8=/.hgtags 2020-01-13 04:57:57.000000000 +0000 @@ -1011,6 +1011,16 @@ 671c4ba50c6f4f9780d40de2549d91f15fcb88d1 jdk8u232-b03 3de2732a8241c8c85a85942f7341ad48491976d9 jdk8u232-b04 415c49110391d46dbb9be24154c2ad1b4157790a jdk8u232-b05 +2338eb5fa755608b47e12ae1d8baa217cd64ee98 jdk8u242-b00 dd568d0e5e10a0dfc05ace7f16bbac5ad6eddde5 jdk8u232-b06 3b3a43588afb9fbdb1b95c475a11d3529a3d9cb5 jdk8u232-b07 4bc16c3608302128648e92c80f3b396372471383 jdk8u232-b08 +735048c9f2d6835b76a436beffd29565f28a2a36 jdk8u232-b09 +735048c9f2d6835b76a436beffd29565f28a2a36 jdk8u232-ga +92a07f0a1bb101933e1c385b7c9d44e3c593e40d jdk8u242-b01 +5b0a0cf41fc1243f32ffe5682ac5dde265902daa jdk8u242-b02 +fbe99e0b4e74edb310cebd774399d80c77be636d jdk8u242-b03 +764b933d3443949279024afa13db853246c4238e jdk8u242-b04 +7f8e21b79cceeda47fb986ecbfd738a08cbb0e54 jdk8u242-b05 +03512b6e35cbe46659ef2568d76836d4fbaa5f25 jdk8u242-b06 +2b1a419389932f0367ab68ad60c4ec209e1ae417 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar8=/src/share/classes/com/sun/tools/javac/jvm/Gen.java openjdk-8-8u242-b08/=unpacked-tar8=/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- openjdk-8-8u232-b09/=unpacked-tar8=/src/share/classes/com/sun/tools/javac/jvm/Gen.java 2019-08-12 20:24:23.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar8=/src/share/classes/com/sun/tools/javac/jvm/Gen.java 2020-01-13 04:57:57.000000000 +0000 @@ -1222,9 +1222,10 @@ code.resolve(c.jumpTrue(), startpc); code.resolve(c.falseJumps); } - code.resolve(loopEnv.info.exit); - if (loopEnv.info.exit != null) { - loopEnv.info.exit.state.defined.excludeFrom(code.nextreg); + Chain exit = loopEnv.info.exit; + if (exit != null) { + code.resolve(exit); + exit.state.defined.excludeFrom(code.nextreg); } } @@ -1235,7 +1236,11 @@ public void visitLabelled(JCLabeledStatement tree) { Env localEnv = env.dup(tree, new GenContext()); genStat(tree.body, localEnv, CRT_STATEMENT); - code.resolve(localEnv.info.exit); + Chain exit = localEnv.info.exit; + if (exit != null) { + code.resolve(exit); + exit.state.defined.excludeFrom(code.nextreg); + } } public void visitSwitch(JCSwitch tree) { @@ -1344,7 +1349,11 @@ } // Resolve all breaks. - code.resolve(switchEnv.info.exit); + Chain exit = switchEnv.info.exit; + if (exit != null) { + code.resolve(exit); + exit.state.defined.excludeFrom(code.nextreg); + } // If we have not set the default offset, we do so now. if (code.get4(tableBase) == -1) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar8=/test/tools/javac/BranchToFewerDefines.java openjdk-8-8u242-b08/=unpacked-tar8=/test/tools/javac/BranchToFewerDefines.java --- openjdk-8-8u232-b09/=unpacked-tar8=/test/tools/javac/BranchToFewerDefines.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar8=/test/tools/javac/BranchToFewerDefines.java 2020-01-13 04:57:57.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8067429 + * @summary java.lang.VerifyError: Inconsistent stackmap frames at branch target + * @author srikanth + * + * @compile BranchToFewerDefines.java + * @run main BranchToFewerDefines + */ + +public class BranchToFewerDefines { + public static void main(String[] args) { + } + private void problematicMethod(int p) { + switch (p) { + case 3: + long n; + while (true) { + if (false) { + break; + } + } + break; + case 2: + loop: while (true) { + while (true) { + int i = 4; + if (p != 16) { + return; + } + break loop; + } + } + break; + default: + while (true) { + if (false) { + break; + } + } + break; + } + long b; + if (p != 7) { + switch (p) { + case 1: + long a = 17; + break; + case 2: + break; + default: + break; + } + } + } + private void problematicMethod2(int p) { + switch (p) { + case 3: + long n; + { + int i = 4; + break; + } + case 2: + { + int i = 4; + break; + } + default: + { + int i = 4; + break; + } + } + long b; + if (p != 7) { + switch (p) { + case 1: + long a = 17; + break; + case 2: + break; + default: + break; + } + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar8=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar8=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar8=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar8=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/.hg_archival.txt openjdk-8-8u242-b08/=unpacked-tar9=/.hg_archival.txt --- openjdk-8-8u232-b09/=unpacked-tar9=/.hg_archival.txt 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/.hg_archival.txt 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,4 @@ repo: a61af66fc99eb5ec9d50c05b0c599757b1289ceb -node: 12177d88b89c12c14daa5ad681030d7551e8a5a0 +node: 7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d branch: default -tag: jdk8u232-b09 -tag: jdk8u232-ga +tag: jdk8u242-b08 diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/.hgtags openjdk-8-8u242-b08/=unpacked-tar9=/.hgtags --- openjdk-8-8u232-b09/=unpacked-tar9=/.hgtags 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/.hgtags 2020-01-13 04:58:01.000000000 +0000 @@ -1279,6 +1279,16 @@ fa7fe6dae563edaae8a8bbe8ac4bd4fa942bde0c jdk8u232-b03 921c5ee7965fdfde75f578ddda24d5cd16f124dc jdk8u232-b04 b13d7942036329f64c77a93cffc25e1b52523a3c jdk8u232-b05 +760b28d871785cd508239a5f635cfb45451f9202 jdk8u242-b00 fea2c7f50ce8e6aee1e946eaec7b834193747d82 jdk8u232-b06 c751303497d539aa85c6373aa0fa85580d3f3044 jdk8u232-b07 4170228e11e6313e948e6ddcae9af3eed06b1fbe jdk8u232-b08 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-b09 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-ga +ce42ae95d4d671f74246091f89bd101d5bcbfd91 jdk8u242-b01 +775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02 +ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03 +20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04 +2c1e9fab6964647f4eeffe55fe5592da6399a3ce jdk8u242-b05 +81ddc1072b923330f84c0ace3124226f63877582 jdk8u242-b06 +8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07 diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/ppc/vm/vm_version_ppc.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/ppc/vm/vm_version_ppc.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/ppc/vm/vm_version_ppc.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/ppc/vm/vm_version_ppc.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -194,6 +194,11 @@ FLAG_SET_DEFAULT(UseAESIntrinsics, false); } + if (UseGHASHIntrinsics) { + warning("GHASH intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + if (has_vshasig()) { if (FLAG_IS_DEFAULT(UseSHA)) { UseSHA = true; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/assembler_sparc.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/assembler_sparc.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/assembler_sparc.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/assembler_sparc.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -129,6 +129,7 @@ flog3_op3 = 0x36, edge_op3 = 0x36, fsrc_op3 = 0x36, + xmulx_op3 = 0x36, impdep2_op3 = 0x37, stpartialf_op3 = 0x37, jmpl_op3 = 0x38, @@ -220,6 +221,8 @@ mdtox_opf = 0x110, mstouw_opf = 0x111, mstosw_opf = 0x113, + xmulx_opf = 0x115, + xmulxhi_opf = 0x116, mxtod_opf = 0x118, mwtos_opf = 0x119, @@ -1212,6 +1215,9 @@ void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + void xmulx(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulx_opf) | rs2(s2)); } + void xmulxhi(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulxhi_opf) | rs2(s2)); } + // Crypto SHA instructions void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/stubGenerator_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/stubGenerator_sparc.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -4788,6 +4788,130 @@ return start; } + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_aligned, L_main; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + Register state = I0; + Register subkeyH = I1; + Register data = I2; + Register len = I3; + + __ save_frame(0); + + __ ldx(state, 0, O0); + __ ldx(state, 8, O1); + + // Loop label for multiblock operations + __ BIND(L_ghash_loop); + + // Check if 'data' is unaligned + __ andcc(data, 7, G1); + __ br(Assembler::zero, false, Assembler::pt, L_aligned); + __ delayed()->nop(); + + Register left_shift = L1; + Register right_shift = L2; + Register data_ptr = L3; + + // Get left and right shift values in bits + __ sll(G1, LogBitsPerByte, left_shift); + __ mov(64, right_shift); + __ sub(right_shift, left_shift, right_shift); + + // Align to read 'data' + __ sub(data, G1, data_ptr); + + // Load first 8 bytes of 'data' + __ ldx(data_ptr, 0, O4); + __ sllx(O4, left_shift, O4); + __ ldx(data_ptr, 8, O5); + __ srlx(O5, right_shift, G4); + __ bset(G4, O4); + + // Load second 8 bytes of 'data' + __ sllx(O5, left_shift, O5); + __ ldx(data_ptr, 16, G4); + __ srlx(G4, right_shift, G4); + __ ba(L_main); + __ delayed()->bset(G4, O5); + + // If 'data' is aligned, load normally + __ BIND(L_aligned); + __ ldx(data, 0, O4); + __ ldx(data, 8, O5); + + __ BIND(L_main); + __ ldx(subkeyH, 0, O2); + __ ldx(subkeyH, 8, O3); + + __ xor3(O0, O4, O0); + __ xor3(O1, O5, O1); + + __ xmulxhi(O0, O3, G3); + __ xmulx(O0, O2, O5); + __ xmulxhi(O1, O2, G4); + __ xmulxhi(O1, O3, G5); + __ xmulx(O0, O3, G1); + __ xmulx(O1, O3, G2); + __ xmulx(O1, O2, O3); + __ xmulxhi(O0, O2, O4); + + __ mov(0xE1, O0); + __ sllx(O0, 56, O0); + + __ xor3(O5, G3, O5); + __ xor3(O5, G4, O5); + __ xor3(G5, G1, G1); + __ xor3(G1, O3, G1); + __ srlx(G2, 63, O1); + __ srlx(G1, 63, G3); + __ sllx(G2, 63, O3); + __ sllx(G2, 58, O2); + __ xor3(O3, O2, O2); + + __ sllx(G1, 1, G1); + __ or3(G1, O1, G1); + + __ xor3(G1, O2, G1); + + __ sllx(G2, 1, G2); + + __ xmulxhi(G1, O0, O1); + __ xmulx(G1, O0, O2); + __ xmulxhi(G2, O0, O3); + __ xmulx(G2, O0, G1); + + __ xor3(O4, O1, O4); + __ xor3(O5, O2, O5); + __ xor3(O5, O3, O5); + + __ sllx(O4, 1, O2); + __ srlx(O5, 63, O3); + + __ or3(O2, O3, O0); + + __ sllx(O5, 1, O1); + __ srlx(G1, 63, O2); + __ or3(O1, O2, O1); + __ xor3(O1, G3, O1); + + __ deccc(len); + __ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop); + __ delayed()->add(data, 16, data); + + __ stx(O0, I0, 0); + __ stx(O1, I0, 8); + + __ ret(); + __ delayed()->restore(); + + return start; + } + void generate_initial() { // Generates all stubs and initializes the entry points @@ -4860,6 +4984,10 @@ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } // generate SHA1/SHA256/SHA512 intrinsics code if (UseSHA1Intrinsics) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/vm_version_sparc.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/vm_version_sparc.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/sparc/vm/vm_version_sparc.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/sparc/vm/vm_version_sparc.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -286,39 +286,50 @@ // SPARC T4 and above should have support for AES instructions if (has_aes()) { - if (UseVIS > 2) { // AES intrinsics use MOVxTOd/MOVdTOx which are VIS3 - if (FLAG_IS_DEFAULT(UseAES)) { - FLAG_SET_DEFAULT(UseAES, true); - } - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - FLAG_SET_DEFAULT(UseAESIntrinsics, true); - } - // we disable both the AES flags if either of them is disabled on the command line - if (!UseAES || !UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAES, false); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + if (FLAG_IS_DEFAULT(UseAES)) { + FLAG_SET_DEFAULT(UseAES, true); + } + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); } else { - if (UseAES || UseAESIntrinsics) { - warning("SPARC AES intrinsics require VIS3 instruction support. Intrinsics will be disabled."); - if (UseAES) { - FLAG_SET_DEFAULT(UseAES, false); - } - if (UseAESIntrinsics) { - FLAG_SET_DEFAULT(UseAESIntrinsics, false); - } + // The AES intrinsic stubs require AES instruction support (of course) + // but also require VIS3 mode or higher for instructions it use. + if (UseVIS > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("SPARC AES intrinsics require VIS3 instructions. Intrinsics will be disabled."); } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } } else if (UseAES || UseAESIntrinsics) { - warning("AES instructions are not available on this CPU"); - if (UseAES) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { + warning("AES instructions are not available on this CPU"); FLAG_SET_DEFAULT(UseAES, false); } - if (UseAESIntrinsics) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); FLAG_SET_DEFAULT(UseAESIntrinsics, false); } } + // GHASH/GCM intrinsics + if (has_vis3() && (UseVIS > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; + } + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times if (has_sha1() || has_sha256() || has_sha512()) { if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -2575,6 +2575,15 @@ emit_int8(shift); } +void Assembler::pslldq(XMMRegister dst, int shift) { + // Shift left 128 bit value in xmm register by number of bytes. + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66); + emit_int8(0x73); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(shift); +} + void Assembler::ptest(XMMRegister dst, Address src) { assert(VM_Version::supports_sse4_1(), ""); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/assembler_x86.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -1527,6 +1527,8 @@ // Shift Right by bytes Logical DoubleQuadword Immediate void psrldq(XMMRegister dst, int shift); + // Shift Left by bytes Logical DoubleQuadword Immediate + void pslldq(XMMRegister dst, int shift); // Logical Compare 128bit void ptest(XMMRegister dst, XMMRegister src); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_32.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_32.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -2719,6 +2719,169 @@ return start; } + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data(0x0b0a0908, relocInfo::none, 0); + __ emit_data(0x0f0e0d0c, relocInfo::none, 0); + __ emit_data(0x03020100, relocInfo::none, 0); + __ emit_data(0x07060504, relocInfo::none, 0); + + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data(0x0c0d0e0f, relocInfo::none, 0); + __ emit_data(0x08090a0b, relocInfo::none, 0); + __ emit_data(0x04050607, relocInfo::none, 0); + __ emit_data(0x00010203, relocInfo::none, 0); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support"); + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = rdi; + const Register subkeyH = rsi; + const Register data = rdx; + const Register blocks = rcx; + + const Address state_param(rbp, 8+0); + const Address subkeyH_param(rbp, 8+4); + const Address data_param(rbp, 8+8); + const Address blocks_param(rbp, 8+12); + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + + __ enter(); + handleSOERegisters(true); // Save registers + + __ movptr(state, state_param); + __ movptr(subkeyH, subkeyH_param); + __ movptr(data, data_param); + __ movptr(blocks, blocks_param); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp6); + __ pslld (xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp4, 31); + __ movdqu(xmm_temp5, xmm_temp7); + __ pslldq(xmm_temp4, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp5, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp4); + __ por(xmm_temp6, xmm_temp5); + + // + // First phase of the reduction + // + // Move xmm3 into xmm4, xmm5, xmm7 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp4, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp5, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp5); + __ movdqu(xmm_temp4, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp4, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm5, xmm7 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp7, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp7); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp4); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + // Byte swap 16-byte result + __ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + __ movdqu(Address(state, 0), xmm_temp6); // store the result + + handleSOERegisters(false); // restore registers + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -3018,6 +3181,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_64.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -3639,6 +3639,175 @@ return start; } + + // byte swap x86 long + address generate_ghash_long_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask"); + address start = __ pc(); + __ emit_data64(0x0f0e0d0c0b0a0908, relocInfo::none ); + __ emit_data64(0x0706050403020100, relocInfo::none ); + return start; + } + + // byte swap x86 byte array + address generate_ghash_byte_swap_mask() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask"); + address start = __ pc(); + __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none ); + __ emit_data64(0x0001020304050607, relocInfo::none ); + return start; + } + + /* Single and multi-block ghash operations */ + address generate_ghash_processBlocks() { + __ align(CodeEntryAlignment); + Label L_ghash_loop, L_exit; + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + address start = __ pc(); + + const Register state = c_rarg0; + const Register subkeyH = c_rarg1; + const Register data = c_rarg2; + const Register blocks = c_rarg3; + +#ifdef _WIN64 + const int XMM_REG_LAST = 10; +#endif + + const XMMRegister xmm_temp0 = xmm0; + const XMMRegister xmm_temp1 = xmm1; + const XMMRegister xmm_temp2 = xmm2; + const XMMRegister xmm_temp3 = xmm3; + const XMMRegister xmm_temp4 = xmm4; + const XMMRegister xmm_temp5 = xmm5; + const XMMRegister xmm_temp6 = xmm6; + const XMMRegister xmm_temp7 = xmm7; + const XMMRegister xmm_temp8 = xmm8; + const XMMRegister xmm_temp9 = xmm9; + const XMMRegister xmm_temp10 = xmm10; + + __ enter(); + +#ifdef _WIN64 + // save the xmm registers which must be preserved 6-10 + __ subptr(rsp, -rsp_after_call_off * wordSize); + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(xmm_save(i), as_XMMRegister(i)); + } +#endif + + __ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); + + __ movdqu(xmm_temp0, Address(state, 0)); + __ pshufb(xmm_temp0, xmm_temp10); + + + __ BIND(L_ghash_loop); + __ movdqu(xmm_temp2, Address(data, 0)); + __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr())); + + __ movdqu(xmm_temp1, Address(subkeyH, 0)); + __ pshufb(xmm_temp1, xmm_temp10); + + __ pxor(xmm_temp0, xmm_temp2); + + // + // Multiply with the hash key + // + __ movdqu(xmm_temp3, xmm_temp0); + __ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0 + __ movdqu(xmm_temp4, xmm_temp0); + __ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1 + + __ movdqu(xmm_temp5, xmm_temp0); + __ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0 + __ movdqu(xmm_temp6, xmm_temp0); + __ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1 + + __ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0 + + __ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5 + __ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right + __ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left + __ pxor(xmm_temp3, xmm_temp5); + __ pxor(xmm_temp6, xmm_temp4); // Register pair holds the result + // of the carry-less multiplication of + // xmm0 by xmm1. + + // We shift the result of the multiplication by one bit position + // to the left to cope for the fact that the bits are reversed. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp6); + __ pslld(xmm_temp3, 1); + __ pslld(xmm_temp6, 1); + __ psrld(xmm_temp7, 31); + __ psrld(xmm_temp8, 31); + __ movdqu(xmm_temp9, xmm_temp7); + __ pslldq(xmm_temp8, 4); + __ pslldq(xmm_temp7, 4); + __ psrldq(xmm_temp9, 12); + __ por(xmm_temp3, xmm_temp7); + __ por(xmm_temp6, xmm_temp8); + __ por(xmm_temp6, xmm_temp9); + + // + // First phase of the reduction + // + // Move xmm3 into xmm7, xmm8, xmm9 in order to perform the shifts + // independently. + __ movdqu(xmm_temp7, xmm_temp3); + __ movdqu(xmm_temp8, xmm_temp3); + __ movdqu(xmm_temp9, xmm_temp3); + __ pslld(xmm_temp7, 31); // packed right shift shifting << 31 + __ pslld(xmm_temp8, 30); // packed right shift shifting << 30 + __ pslld(xmm_temp9, 25); // packed right shift shifting << 25 + __ pxor(xmm_temp7, xmm_temp8); // xor the shifted versions + __ pxor(xmm_temp7, xmm_temp9); + __ movdqu(xmm_temp8, xmm_temp7); + __ pslldq(xmm_temp7, 12); + __ psrldq(xmm_temp8, 4); + __ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete + + // + // Second phase of the reduction + // + // Make 3 copies of xmm3 in xmm2, xmm4, xmm5 for doing these + // shift operations. + __ movdqu(xmm_temp2, xmm_temp3); + __ movdqu(xmm_temp4, xmm_temp3); + __ movdqu(xmm_temp5, xmm_temp3); + __ psrld(xmm_temp2, 1); // packed left shifting >> 1 + __ psrld(xmm_temp4, 2); // packed left shifting >> 2 + __ psrld(xmm_temp5, 7); // packed left shifting >> 7 + __ pxor(xmm_temp2, xmm_temp4); // xor the shifted versions + __ pxor(xmm_temp2, xmm_temp5); + __ pxor(xmm_temp2, xmm_temp8); + __ pxor(xmm_temp3, xmm_temp2); + __ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6 + + __ decrement(blocks); + __ jcc(Assembler::zero, L_exit); + __ movdqu(xmm_temp0, xmm_temp6); + __ addptr(data, 16); + __ jmp(L_ghash_loop); + + __ BIND(L_exit); + __ pshufb(xmm_temp6, xmm_temp10); // Byte swap 16-byte result + __ movdqu(Address(state, 0), xmm_temp6); // store the result + +#ifdef _WIN64 + // restore xmm regs belonging to calling function + for (int i = 6; i <= XMM_REG_LAST; i++) { + __ movdqu(as_XMMRegister(i), xmm_save(i)); + } +#endif + __ leave(); + __ ret(0); + return start; + } + /** * Arguments: * @@ -4077,6 +4246,13 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + // Generate GHASH intrinsics code + if (UseGHASHIntrinsics) { + StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask(); + StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + // Safefetch stubs. generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -33,6 +33,8 @@ address StubRoutines::x86::_verify_mxcsr_entry = NULL; address StubRoutines::x86::_key_shuffle_mask_addr = NULL; +address StubRoutines::x86::_ghash_long_swap_mask_addr = NULL; +address StubRoutines::x86::_ghash_byte_swap_mask_addr = NULL; uint64_t StubRoutines::x86::_crc_by128_masks[] = { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/stubRoutines_x86.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,10 +36,15 @@ // masks and table for CRC32 static uint64_t _crc_by128_masks[]; static juint _crc_table[]; + // swap mask for ghash + static address _ghash_long_swap_mask_addr; + static address _ghash_byte_swap_mask_addr; public: static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } static address crc_by128_masks_addr() { return (address)_crc_by128_masks; } + static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; } + static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; } #endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/vm_version_x86.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/vm_version_x86.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/cpu/x86/vm/vm_version_x86.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/cpu/x86/vm/vm_version_x86.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -553,12 +553,36 @@ // Use AES instructions if available. if (supports_aes()) { if (FLAG_IS_DEFAULT(UseAES)) { - UseAES = true; + FLAG_SET_DEFAULT(UseAES, true); } - } else if (UseAES) { - if (!FLAG_IS_DEFAULT(UseAES)) + if (!UseAES) { + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else { + if (UseSSE > 2) { + if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { + FLAG_SET_DEFAULT(UseAESIntrinsics, true); + } + } else { + // The AES intrinsic stubs require AES instruction support (of course) + // but also require sse3 mode or higher for instructions it use. + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("X86 AES intrinsics require SSE3 instructions or higher. Intrinsics will be disabled."); + } + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + } + } else if (UseAES || UseAESIntrinsics) { + if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { warning("AES instructions are not available on this CPU"); - FLAG_SET_DEFAULT(UseAES, false); + FLAG_SET_DEFAULT(UseAES, false); + } + if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } } // Use CLMUL instructions if available. @@ -582,16 +606,15 @@ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); } - // The AES intrinsic stubs require AES instruction support (of course) - // but also require sse3 mode for instructions it use. - if (UseAES && (UseSSE > 2)) { - if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { - UseAESIntrinsics = true; + // GHASH/GCM intrinsics + if (UseCLMUL && (UseSSE > 2)) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { + UseGHASHIntrinsics = true; } - } else if (UseAESIntrinsics) { - if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) - warning("AES intrinsics are not available on this CPU"); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } else if (UseGHASHIntrinsics) { + if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics)) + warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } if (UseSHA) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/c1/c1_LIR.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/c1/c1_LIR.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/c1/c1_LIR.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/c1/c1_LIR.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -2112,8 +2112,14 @@ // LIR_OpProfileType void LIR_OpProfileType::print_instr(outputStream* out) const { - out->print("exact = "); exact_klass()->print_name_on(out); - out->print("current = "); ciTypeEntries::print_ciklass(out, current_klass()); + out->print("exact = "); + if (exact_klass() == NULL) { + out->print("unknown"); + } else { + exact_klass()->print_name_on(out); + } + out->print(" current = "); ciTypeEntries::print_ciklass(out, current_klass()); + out->print(" "); mdp()->print(out); out->print(" "); obj()->print(out); out->print(" "); tmp()->print(out); out->print(" "); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/classfile/vmSymbols.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/classfile/vmSymbols.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/classfile/vmSymbols.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/classfile/vmSymbols.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -863,6 +863,12 @@ do_name( implCompressMB_name, "implCompressMultiBlock0") \ do_signature(implCompressMB_signature, "([BII)I") \ \ + /* support for com.sun.crypto.provider.GHASH */ \ + do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH") \ + do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \ + do_name(processBlocks_name, "processBlocks") \ + do_signature(ghash_processBlocks_signature, "([BII[J[J)V") \ + \ /* support for java.util.zip */ \ do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \ do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -161,6 +161,8 @@ } _dictionary->set_par_lock(&_parDictionaryAllocLock); } + + _used_stable = 0; } // Like CompactibleSpace forward() but always calls cross_threshold() to @@ -377,6 +379,14 @@ return capacity() - free(); } +size_t CompactibleFreeListSpace::used_stable() const { + return _used_stable; +} + +void CompactibleFreeListSpace::recalculate_used_stable() { + _used_stable = used(); +} + size_t CompactibleFreeListSpace::free() const { // "MT-safe, but not MT-precise"(TM), if you will: i.e. // if you do this while the structures are in flux you @@ -1218,6 +1228,13 @@ debug_only(fc->mangleAllocated(size)); } + // During GC we do not need to recalculate the stable used value for + // every allocation in old gen. It is done once at the end of GC instead + // for performance reasons. + if (!Universe::heap()->is_gc_active()) { + recalculate_used_stable(); + } + return res; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -148,6 +148,9 @@ // Used to keep track of limit of sweep for the space HeapWord* _sweep_limit; + // Stable value of used(). + size_t _used_stable; + // Support for compacting cms HeapWord* cross_threshold(HeapWord* start, HeapWord* end); HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); @@ -343,6 +346,17 @@ // which overestimates the region by returning the entire // committed region (this is safe, but inefficient). + // Returns monotonically increasing stable used space bytes for CMS. + // This is required for jstat and other memory monitoring tools + // that might otherwise see inconsistent used space values during a garbage + // collection, promotion or allocation into compactibleFreeListSpace. + // The value returned by this function might be smaller than the + // actual value. + size_t used_stable() const; + // Recalculate and cache the current stable used() value. Only to be called + // in places where we can be sure that the result is stable. + void recalculate_used_stable(); + // Returns a subregion of the space containing all the objects in // the space. MemRegion used_region() const { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -869,6 +869,10 @@ return _cmsSpace->max_alloc_in_words() * HeapWordSize; } +size_t ConcurrentMarkSweepGeneration::used_stable() const { + return cmsSpace()->used_stable(); +} + size_t ConcurrentMarkSweepGeneration::max_available() const { return free() + _virtual_space.uncommitted_size(); } @@ -1955,6 +1959,8 @@ FreelistLocker z(this); MetaspaceGC::compute_new_size(); _cmsGen->compute_new_size_free_list(); + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); } // A work method used by foreground collection to determine @@ -2768,6 +2774,7 @@ _capacity_at_prologue = capacity(); _used_at_prologue = used(); + _cmsSpace->recalculate_used_stable(); // Delegate to CMScollector which knows how to coordinate between // this and any other CMS generations that it is responsible for @@ -2837,6 +2844,7 @@ _eden_chunk_index = 0; size_t cms_used = _cmsGen->cmsSpace()->used(); + _cmsGen->cmsSpace()->recalculate_used_stable(); // update performance counters - this uses a special version of // update_counters() that allows the utilization to be passed as a @@ -3672,6 +3680,7 @@ _collectorState = Marking; } SpecializationStats::print(); + _cmsGen->cmsSpace()->recalculate_used_stable(); } void CMSCollector::checkpointRootsInitialWork(bool asynch) { @@ -5066,10 +5075,12 @@ Mutex::_no_safepoint_check_flag); assert(!init_mark_was_synchronous, "but that's impossible!"); checkpointRootsFinalWork(asynch, clear_all_soft_refs, false); + _cmsGen->cmsSpace()->recalculate_used_stable(); } else { // already have all the locks checkpointRootsFinalWork(asynch, clear_all_soft_refs, init_mark_was_synchronous); + _cmsGen->cmsSpace()->recalculate_used_stable(); } verify_work_stacks_empty(); verify_overflow_empty(); @@ -6368,6 +6379,10 @@ // Update heap occupancy information which is used as // input to soft ref clearing policy at the next gc. Universe::update_heap_info_at_gc(); + + // recalculate CMS used space after CMS collection + _cmsGen->cmsSpace()->recalculate_used_stable(); + _collectorState = Resizing; } } else { @@ -6467,6 +6482,7 @@ // Gather statistics on the young generation collection. collector()->stats().record_gc0_end(used()); } + _cmsSpace->recalculate_used_stable(); } CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -1190,6 +1190,7 @@ double occupancy() const { return ((double)used())/((double)capacity()); } size_t contiguous_available() const; size_t unsafe_max_alloc_nogc() const; + size_t used_stable() const; // over-rides MemRegion used_region() const; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -2520,6 +2520,12 @@ } } } + } else if (GC_locker::should_discard(cause, gc_count_before)) { + // Return to be consistent with VMOp failure due to another + // collection slipping in after our gc_count but before our + // request is processed. _gc_locker collections upgraded by + // GCLockerInvokesConcurrent are handled above and never discarded. + return; } else { if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -376,7 +376,7 @@ MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes), 1U); _sizer_kind = SizerMaxAndNewSize; - _adaptive_size = _min_desired_young_length == _max_desired_young_length; + _adaptive_size = _min_desired_young_length != _max_desired_young_length; } else { _sizer_kind = SizerNewSizeOnly; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -133,7 +133,11 @@ SizerKind _sizer_kind; uint _min_desired_young_length; uint _max_desired_young_length; + + // False when using a fixed young generation size due to command-line options, + // true otherwise. bool _adaptive_size; + uint calculate_default_min_length(uint new_number_of_heap_regions); uint calculate_default_max_length(uint new_number_of_heap_regions); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -530,6 +530,10 @@ full_gc_count = Universe::heap()->total_full_collections(); } + if (GC_locker::should_discard(cause, gc_count)) { + return; + } + VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); VMThread::execute(&op); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -52,11 +52,16 @@ } } +static bool is_cause_full(GCCause::Cause cause) { + return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc) + DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot)); +} + // Only used for System.gc() calls VM_ParallelGCSystemGC::VM_ParallelGCSystemGC(uint gc_count, uint full_gc_count, GCCause::Cause gc_cause) : - VM_GC_Operation(gc_count, gc_cause, full_gc_count, true /* full */) + VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause)) { } @@ -68,8 +73,7 @@ "must be a ParallelScavengeHeap"); GCCauseSetter gccs(heap, _gc_cause); - if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc - DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) { + if (!_full) { // If (and only if) the scavenge fails, this will invoke a full gc. heap->invoke_scavenge(); } else { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -63,7 +63,7 @@ } inline void update_used() { - _used->set_value(_gen->used()); + _used->set_value(_gen->used_stable()); } // special version of update_used() to allow the used value to be @@ -107,7 +107,7 @@ GenerationUsedHelper(Generation* g) : _gen(g) { } inline jlong take_sample() { - return _gen->used(); + return _gen->used_stable(); } }; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -201,6 +201,19 @@ } } +static bool is_full_gc(int max_level) { + // Return true if max_level is all generations + return (max_level == (GenCollectedHeap::heap()->n_gens() - 1)); +} + +VM_GenCollectFull::VM_GenCollectFull(uint gc_count_before, + uint full_gc_count_before, + GCCause::Cause gc_cause, + int max_level) : + VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, + is_full_gc(max_level) /* full */), + _max_level(max_level) { } + void VM_GenCollectFull::doit() { SvcGCMarker sgcm(SvcGCMarker::FULL); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -201,9 +201,7 @@ VM_GenCollectFull(uint gc_count_before, uint full_gc_count_before, GCCause::Cause gc_cause, - int max_level) - : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */), - _max_level(max_level) { } + int max_level); ~VM_GenCollectFull() {} virtual VMOp_Type type() const { return VMOp_GenCollectFull; } virtual void doit(); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/gcLocker.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/gcLocker.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/gcLocker.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/gcLocker.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -31,6 +31,7 @@ volatile jint GC_locker::_jni_lock_count = 0; volatile bool GC_locker::_needs_gc = false; volatile bool GC_locker::_doing_gc = false; +unsigned int GC_locker::_total_collections = 0; #ifdef ASSERT volatile jint GC_locker::_debug_jni_lock_count = 0; @@ -94,6 +95,11 @@ } } +bool GC_locker::should_discard(GCCause::Cause cause, uint total_collections) { + return (cause == GCCause::_gc_locker) && + (_total_collections != total_collections); +} + void GC_locker::jni_lock(JavaThread* thread) { assert(!thread->in_critical(), "shouldn't currently be in a critical region"); MutexLocker mu(JNICritical_lock); @@ -117,7 +123,13 @@ decrement_debug_jni_lock_count(); thread->exit_critical(); if (needs_gc() && !is_active_internal()) { - // We're the last thread out. Cause a GC to occur. + // We're the last thread out. Request a GC. + // Capture the current total collections, to allow detection of + // other collections that make this one unnecessary. The value of + // total_collections() is only changed at a safepoint, so there + // must not be a safepoint between the lock becoming inactive and + // getting the count, else there may be unnecessary GCLocker GCs. + _total_collections = Universe::heap()->total_collections(); _doing_gc = true; { // Must give up the lock while at a safepoint diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/gcLocker.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/gcLocker.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/gcLocker.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/gcLocker.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -26,6 +26,7 @@ #define SHARE_VM_MEMORY_GCLOCKER_HPP #include "gc_interface/collectedHeap.hpp" +#include "gc_interface/gcCause.hpp" #include "memory/genCollectedHeap.hpp" #include "memory/universe.hpp" #include "oops/oop.hpp" @@ -57,6 +58,7 @@ static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC + static uint _total_collections; // value for _gc_locker collection #ifdef ASSERT // This lock count is updated for all operations and is used to @@ -116,6 +118,12 @@ // Sets _needs_gc if is_active() is true. Returns is_active(). static bool check_active_before_gc(); + // Return true if the designated collection is a GCLocker request + // that should be discarded. Returns true if cause == GCCause::_gc_locker + // and the given total collection value indicates a collection has been + // done since the GCLocker request was made. + static bool should_discard(GCCause::Cause cause, uint total_collections); + // Stalls the caller (who should not be in a jni critical section) // until needs_gc() clears. Note however that needs_gc() may be // set at a subsequent safepoint and/or cleared under the diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/genCollectedHeap.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/genCollectedHeap.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/genCollectedHeap.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/genCollectedHeap.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -796,8 +796,11 @@ #else // INCLUDE_ALL_GCS ShouldNotReachHere(); #endif // INCLUDE_ALL_GCS - } else if (cause == GCCause::_wb_young_gc) { - // minor collection for WhiteBox API + } else if ((cause == GCCause::_wb_young_gc) || + (cause == GCCause::_gc_locker)) { + // minor collection for WhiteBox or GCLocker. + // _gc_locker collections upgraded by GCLockerInvokesConcurrent + // are handled above and never discarded. collect(cause, 0); } else { #ifdef ASSERT @@ -835,6 +838,11 @@ // Read the GC count while holding the Heap_lock unsigned int gc_count_before = total_collections(); unsigned int full_gc_count_before = total_full_collections(); + + if (GC_locker::should_discard(cause, gc_count_before)) { + return; + } + { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back VM_GenCollectFull op(gc_count_before, full_gc_count_before, @@ -887,24 +895,16 @@ void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, int max_level) { - int local_max_level; - if (!incremental_collection_will_fail(false /* don't consult_young */) && - gc_cause() == GCCause::_gc_locker) { - local_max_level = 0; - } else { - local_max_level = max_level; - } do_collection(true /* full */, clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - local_max_level /* max_level */); + max_level /* max_level */); // Hack XXX FIX ME !!! // A scavenge may not have been attempted, or may have // been attempted and failed, because the old gen was too full - if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker && - incremental_collection_will_fail(false /* don't consult_young */)) { + if (gc_cause() == GCCause::_gc_locker && incremental_collection_failed()) { if (PrintGCDetails) { gclog_or_tty->print_cr("GC locker: Trying a full collection " "because scavenge failed"); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/generation.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/generation.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/generation.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/generation.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -68,6 +68,12 @@ return gch->_gen_specs[level()]; } +// This is for CMS. It returns stable monotonic used space size. +// Remove this when CMS is removed. +size_t Generation::used_stable() const { + return used(); +} + size_t Generation::max_capacity() const { return reserved().byte_size(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/generation.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/generation.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/memory/generation.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/memory/generation.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -168,6 +168,7 @@ virtual size_t capacity() const = 0; // The maximum number of object bytes the // generation can currently hold. virtual size_t used() const = 0; // The number of used bytes in the gen. + virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools. virtual size_t free() const = 0; // The number of free bytes in the gen. // Support for java.lang.Runtime.maxMemory(); see CollectedHeap. diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/instanceKlass.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/instanceKlass.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/instanceKlass.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/instanceKlass.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -294,6 +294,7 @@ set_has_unloaded_dependent(false); set_init_state(InstanceKlass::allocated); set_init_thread(NULL); + set_init_state(allocated); set_reference_type(rt); set_oop_map_cache(NULL); set_jni_ids(NULL); @@ -978,11 +979,13 @@ oop init_lock = this_oop->init_lock(); if (init_lock != NULL) { ObjectLocker ol(init_lock, THREAD); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); this_oop->fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(init_lock != NULL, "The initialization state should never be set twice"); + this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state this_oop->set_init_state(state); } } @@ -3602,6 +3605,7 @@ bool good_state = is_shared() ? (_init_state <= state) : (_init_state < state); assert(good_state || state == allocated, "illegal state transition"); + assert(_init_thread == NULL, "should be cleared before state change"); _init_state = (u1)state; } #endif diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/instanceKlass.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/instanceKlass.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/instanceKlass.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/instanceKlass.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -241,7 +241,7 @@ u2 _misc_flags; u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file - Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) + Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/klassVtable.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/klassVtable.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/oops/klassVtable.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/oops/klassVtable.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -289,22 +289,25 @@ int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { InstanceKlass* superk = initialsuper; while (superk != NULL && superk->super() != NULL) { - InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); - klassVtable* ssVtable = supersuperklass->vtable(); + klassVtable* ssVtable = (superk->super())->vtable(); if (vtable_index < ssVtable->length()) { Method* super_method = ssVtable->method_at(vtable_index); + // get the class holding the matching method + // make sure you use that class for is_override + InstanceKlass* supermethodholder = super_method->method_holder(); #ifndef PRODUCT Symbol* name= target_method()->name(); Symbol* signature = target_method()->signature(); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif - if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { + + if (supermethodholder->is_override(super_method, target_loader, target_classname, THREAD)) { #ifndef PRODUCT if (PrintVtables && Verbose) { ResourceMark rm(THREAD); char* sig = target_method()->name_and_sig_as_C_string(); tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", - supersuperklass->internal_name(), + supermethodholder->internal_name(), _klass->internal_name(), sig, vtable_index); super_method->access_flags().print_on(tty); if (super_method->is_default_method()) { @@ -656,7 +659,7 @@ // search through the super class hierarchy to see if we need // a new entry - ResourceMark rm; + ResourceMark rm(THREAD); Symbol* name = target_method()->name(); Symbol* signature = target_method()->signature(); Klass* k = super; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/escape.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/escape.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/escape.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/escape.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -952,6 +952,7 @@ strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || + strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 || @@ -2114,6 +2115,9 @@ return false; } PointsToNode* ptn = ptnode_adr(idx); + if (ptn == NULL) { + return false; // not in congraph (e.g. ConI) + } PointsToNode::EscapeState es = ptn->escape_state(); // If we have already computed a value, return it. if (es >= PointsToNode::GlobalEscape) diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/library_call.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/library_call.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/library_call.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/library_call.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -311,6 +311,7 @@ Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); + bool inline_ghash_processBlocks(); bool inline_sha_implCompress(vmIntrinsics::ID id); bool inline_digestBase_implCompressMB(int predicate); bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, @@ -570,6 +571,10 @@ predicates = 3; break; + case vmIntrinsics::_ghash_processBlocks: + if (!UseGHASHIntrinsics) return NULL; + break; + case vmIntrinsics::_updateCRC32: case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: @@ -957,6 +962,9 @@ case vmIntrinsics::_montgomerySquare: return inline_montgomerySquare(); + case vmIntrinsics::_ghash_processBlocks: + return inline_ghash_processBlocks(); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -6599,6 +6607,35 @@ return _gvn.transform(region); } +//------------------------------inline_ghash_processBlocks +bool LibraryCallKit::inline_ghash_processBlocks() { + address stubAddr; + const char *stubName; + assert(UseGHASHIntrinsics, "need GHASH intrinsics support"); + + stubAddr = StubRoutines::ghash_processBlocks(); + stubName = "ghash_processBlocks"; + + Node* data = argument(0); + Node* offset = argument(1); + Node* len = argument(2); + Node* state = argument(3); + Node* subkeyH = argument(4); + + Node* state_start = array_element_address(state, intcon(0), T_LONG); + assert(state_start, "state is NULL"); + Node* subkeyH_start = array_element_address(subkeyH, intcon(0), T_LONG); + assert(subkeyH_start, "subkeyH is NULL"); + Node* data_start = array_element_address(data, offset, T_BYTE); + assert(data_start, "data is NULL"); + + Node* ghash = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::ghash_processBlocks_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + state_start, subkeyH_start, data_start, len); + return true; +} + //------------------------------inline_sha_implCompress----------------------- // // Calculate SHA (i.e., SHA-1) for single-block byte[] array. diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopnode.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopnode.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopnode.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopnode.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -279,6 +279,7 @@ if (iv_phi == NULL) { return NULL; } + assert(iv_phi->is_Phi(), "should be PhiNode"); Node *ln = iv_phi->in(0); if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) { return (CountedLoopNode*)ln; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopopts.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopopts.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopopts.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopopts.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -309,7 +309,7 @@ } return NULL; } - assert(m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); + assert(n->is_Phi() || m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); } return n_ctrl; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopTransform.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopTransform.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/loopTransform.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/loopTransform.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2231,6 +2231,13 @@ // We also need to replace the original limit to collapse loop exit. Node* cmp = cl->loopexit()->cmp_node(); assert(cl->limit() == cmp->in(2), "sanity"); + // Duplicate cmp node if it has other users + if (cmp->outcnt() > 1) { + cmp = cmp->clone(); + cmp = phase->_igvn.register_new_node_with_optimizer(cmp); + BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool(); + phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist + } phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/runtime.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/runtime.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/runtime.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/runtime.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -92,7 +92,25 @@ // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000 +// GHASH block processing +const TypeFunc* OptoRuntime::ghash_processBlocks_Type() { + int argcnt = 4; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypePtr::NOTNULL; // subkeyH + fields[argp++] = TypePtr::NOTNULL; // data + fields[argp++] = TypeInt::INT; // blocks + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = NULL; // void + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); +} // Compiled code entry points address OptoRuntime::_new_instance_Java = NULL; diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/runtime.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/runtime.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/runtime.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/runtime.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -311,6 +311,8 @@ static const TypeFunc* montgomeryMultiply_Type(); static const TypeFunc* montgomerySquare_Type(); + static const TypeFunc* ghash_processBlocks_Type(); + static const TypeFunc* updateBytesCRC32_Type(); // leaf on stack replacement interpreter accessor types diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/superword.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/superword.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/opto/superword.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/opto/superword.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -448,6 +448,7 @@ return true; // no induction variable } CountedLoopEndNode* pre_end = get_pre_loop_end(lp()->as_CountedLoop()); + assert(pre_end != NULL, "we must have a correct pre-loop"); assert(pre_end->stride_is_con(), "pre loop stride is constant"); int preloop_stride = pre_end->stride_con(); @@ -2052,7 +2053,7 @@ CountedLoopNode *main_head = lp()->as_CountedLoop(); assert(main_head->is_main_loop(), ""); CountedLoopEndNode* pre_end = get_pre_loop_end(main_head); - assert(pre_end != NULL, ""); + assert(pre_end != NULL, "we must have a correct pre-loop"); Node *pre_opaq1 = pre_end->limit(); assert(pre_opaq1->Opcode() == Op_Opaque1, ""); Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1; @@ -2207,16 +2208,27 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. -CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) { - Node *ctrl = cl->in(LoopNode::EntryControl); +CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { + Node* ctrl = cl->in(LoopNode::EntryControl); if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node *iffm = ctrl->in(0); + Node* iffm = ctrl->in(0); if (!iffm->is_If()) return NULL; - Node *p_f = iffm->in(0); + Node* bolzm = iffm->in(1); + if (!bolzm->is_Bool()) return NULL; + Node* cmpzm = bolzm->in(1); + if (!cmpzm->is_Cmp()) return NULL; + Node* opqzm = cmpzm->in(2); + // Can not optimize a loop if zero-trip Opaque1 node is optimized + // away and then another round of loop opts attempted. + if (opqzm->Opcode() != Op_Opaque1) { + return NULL; + } + Node* p_f = iffm->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; - CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); - if (!pre_end->loopnode()->is_pre_loop()) return NULL; + CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); + CountedLoopNode* loop_node = pre_end->loopnode(); + if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL; return pre_end; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/globals.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/globals.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/globals.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/globals.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -602,6 +602,9 @@ product(bool, UseSHA, false, \ "Control whether SHA instructions can be used on SPARC") \ \ + product(bool, UseGHASHIntrinsics, false, \ + "Use intrinsics for GHASH versions of crypto") \ + \ product(uintx, LargePageSizeInBytes, 0, \ "Large page size (0 to let VM choose the page size)") \ \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/safepoint.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/safepoint.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/safepoint.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/safepoint.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -537,6 +537,7 @@ // rotate log files? if (UseGCLogFileRotation) { + TraceTime t8("rotating gc logs", TraceSafepointCleanupTime); gclog_or_tty->rotate_log(false); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -124,6 +124,7 @@ address StubRoutines::_aescrypt_decryptBlock = NULL; address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL; address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL; +address StubRoutines::_ghash_processBlocks = NULL; address StubRoutines::_sha1_implCompress = NULL; address StubRoutines::_sha1_implCompressMB = NULL; @@ -176,7 +177,7 @@ StubGenerator_generate(&buffer, false); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size1"); + assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1"); } } @@ -231,7 +232,7 @@ StubGenerator_generate(&buffer, true); // When new stubs added we need to make sure there is some space left // to catch situation when we should increase size again. - assert(buffer.insts_remaining() > 200, "increase code_size2"); + assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2"); } #ifdef ASSERT diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/stubRoutines.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -197,6 +197,7 @@ static address _aescrypt_decryptBlock; static address _cipherBlockChaining_encryptAESCrypt; static address _cipherBlockChaining_decryptAESCrypt; + static address _ghash_processBlocks; static address _sha1_implCompress; static address _sha1_implCompressMB; @@ -359,6 +360,7 @@ static address aescrypt_decryptBlock() { return _aescrypt_decryptBlock; } static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; } static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; } + static address ghash_processBlocks() { return _ghash_processBlocks; } static address sha1_implCompress() { return _sha1_implCompress; } static address sha1_implCompressMB() { return _sha1_implCompressMB; } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/vmStructs.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/vmStructs.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/runtime/vmStructs.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/runtime/vmStructs.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -810,6 +810,7 @@ static_field(StubRoutines, _aescrypt_decryptBlock, address) \ static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _ghash_processBlocks, address) \ static_field(StubRoutines, _updateBytesCRC32, address) \ static_field(StubRoutines, _crc_table_adr, address) \ static_field(StubRoutines, _multiplyToLen, address) \ diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/allocationSite.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/allocationSite.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/allocationSite.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/allocationSite.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -34,8 +34,9 @@ private: NativeCallStack _call_stack; E e; + MEMFLAGS _flag; public: - AllocationSite(const NativeCallStack& stack) : _call_stack(stack) { } + AllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : _call_stack(stack), _flag(flag) { } int hash() const { return _call_stack.hash(); } bool equals(const NativeCallStack& stack) const { return _call_stack.equals(stack); @@ -52,6 +53,8 @@ // Information regarding this allocation E* data() { return &e; } const E* peek() const { return &e; } + + MEMFLAGS flag() const { return _flag; } }; #endif // SHARE_VM_SERVICES_ALLOCATION_SITE_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,12 +84,18 @@ // Create pseudo call stack for hashtable entry allocation address pc[3]; if (NMT_TrackingStackDepth >= 3) { - pc[2] = (address)MallocSiteTable::allocation_at; + uintx *fp = (uintx*)MallocSiteTable::allocation_at; + // On ppc64, 'fp' is a pointer to a function descriptor which is a struct of + // three native pointers where the first pointer is the real function address. + // See: http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES + pc[2] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } if (NMT_TrackingStackDepth >= 2) { - pc[1] = (address)MallocSiteTable::lookup_or_add; + uintx *fp = (uintx*)MallocSiteTable::lookup_or_add; + pc[1] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); } - pc[0] = (address)MallocSiteTable::new_entry; + uintx *fp = (uintx*)MallocSiteTable::new_entry; + pc[0] = (address)(fp PPC64_ONLY(BIG_ENDIAN_ONLY([0]))); // Instantiate NativeCallStack object, have to use placement new operator. (see comments above) NativeCallStack* stack = ::new ((void*)_hash_entry_allocation_stack) @@ -158,7 +164,7 @@ MallocSiteHashtableEntry* head = _table[index]; while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { MallocSite* site = head->data(); - if (site->flags() == flags && site->equals(key)) { + if (site->flag() == flags && site->equals(key)) { return head->data(); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/mallocSiteTable.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -37,15 +37,12 @@ // MallocSite represents a code path that eventually calls // os::malloc() to allocate memory class MallocSite : public AllocationSite { - private: - MEMFLAGS _flags; - public: MallocSite() : - AllocationSite(NativeCallStack::empty_stack()), _flags(mtNone) {} + AllocationSite(NativeCallStack::empty_stack(), mtNone) {} MallocSite(const NativeCallStack& stack, MEMFLAGS flags) : - AllocationSite(stack), _flags(flags) {} + AllocationSite(stack, flags) {} void allocate(size_t size) { data()->allocate(size); } @@ -55,7 +52,6 @@ size_t size() const { return peek()->size(); } // The number of calls were made size_t count() const { return peek()->count(); } - MEMFLAGS flags() const { return (MEMFLAGS)_flags; } }; // Malloc site hashtable entry diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memBaseline.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memBaseline.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memBaseline.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memBaseline.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) { int res = compare_malloc_site(s1, s2); if (res == 0) { - res = (int)(s1.flags() - s2.flags()); + res = (int)(s1.flag() - s2.flag()); } return res; @@ -209,7 +209,7 @@ const ReservedMemoryRegion* rgn; VirtualMemoryAllocationSite* site; while ((rgn = itr.next()) != NULL) { - VirtualMemoryAllocationSite tmp(*rgn->call_stack()); + VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag()); site = allocation_sites.find(tmp); if (site == NULL) { LinkedListNode* node = diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memoryPool.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memoryPool.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memoryPool.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memoryPool.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -198,7 +198,7 @@ bool support_usage_threshold); MemoryUsage get_memory_usage(); - size_t used_in_bytes() { return _space->used(); } + size_t used_in_bytes() { return _space->used_stable(); } }; #endif // INCLUDE_ALL_GCS diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memReporter.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memReporter.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memReporter.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memReporter.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -205,7 +205,7 @@ const NativeCallStack* stack = malloc_site->call_stack(); stack->print_on(out); out->print("%29s", " "); - MEMFLAGS flag = malloc_site->flags(); + MEMFLAGS flag = malloc_site->flag(); assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone, "Must have a valid memory type"); print_malloc(malloc_site->size(), malloc_site->count(),flag); @@ -231,6 +231,10 @@ stack->print_on(out); out->print("%28s (", " "); print_total(virtual_memory_site->reserved(), virtual_memory_site->committed()); + MEMFLAGS flag = virtual_memory_site->flag(); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } out->print_cr(")\n"); } } @@ -562,24 +566,24 @@ void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(), - 0, 0, malloc_site->flags()); + 0, 0, malloc_site->flag()); } void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const { diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(), - malloc_site->count(), malloc_site->flags()); + malloc_site->count(), malloc_site->flag()); } void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early, const MallocSite* current) const { - if (early->flags() != current->flags()) { + if (early->flag() != current->flag()) { // If malloc site type changed, treat it as deallocation of old type and // allocation of new type. old_malloc_site(early); new_malloc_site(current); } else { diff_malloc_site(current->call_stack(), current->size(), current->count(), - early->size(), early->count(), early->flags()); + early->size(), early->count(), early->flag()); } } @@ -603,21 +607,22 @@ void MemDetailDiffReporter::new_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0); + diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0, site->flag()); } void MemDetailDiffReporter::old_virtual_memory_site(const VirtualMemoryAllocationSite* site) const { - diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed()); + diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed(), site->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, const VirtualMemoryAllocationSite* current) const { + assert(early->flag() == current->flag(), "Should be the same"); diff_virtual_memory_site(current->call_stack(), current->reserved(), current->committed(), - early->reserved(), early->committed()); + early->reserved(), early->committed(), current->flag()); } void MemDetailDiffReporter::diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const { + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const { outputStream* out = output(); // no change @@ -631,6 +636,10 @@ print_virtual_memory_diff(current_reserved, current_committed, early_reserved, early_committed); + if (flag != mtNone) { + out->print(" Type=%s", NMTUtil::flag_to_name(flag)); + } + out->print_cr(")\n"); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memReporter.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memReporter.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/memReporter.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/memReporter.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -218,7 +218,7 @@ void diff_malloc_site(const NativeCallStack* stack, size_t current_size, size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const; void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, - size_t current_committed, size_t early_reserved, size_t early_committed) const; + size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; }; #endif // INCLUDE_NMT diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/virtualMemoryTracker.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/virtualMemoryTracker.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/services/virtualMemoryTracker.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/services/virtualMemoryTracker.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -69,8 +69,8 @@ // Virtual memory allocation site, keeps track where the virtual memory is reserved. class VirtualMemoryAllocationSite : public AllocationSite { public: - VirtualMemoryAllocationSite(const NativeCallStack& stack) : - AllocationSite(stack) { } + VirtualMemoryAllocationSite(const NativeCallStack& stack, MEMFLAGS flag) : + AllocationSite(stack, flag) { } inline void reserve_memory(size_t sz) { data()->reserve_memory(sz); } inline void commit_memory (size_t sz) { data()->commit_memory(sz); } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/macros.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/macros.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/macros.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/macros.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -416,6 +416,14 @@ #define NOT_EMBEDDED(code) code #endif +#ifdef VM_LITTLE_ENDIAN +#define LITTLE_ENDIAN_ONLY(code) code +#define BIG_ENDIAN_ONLY(code) +#else +#define LITTLE_ENDIAN_ONLY(code) +#define BIG_ENDIAN_ONLY(code) code +#endif + #define define_pd_global(type, name, value) const type pd_##name = value; #endif // SHARE_VM_UTILITIES_MACROS_HPP diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/taskqueue.hpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/taskqueue.hpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/taskqueue.hpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/taskqueue.hpp 2020-01-13 04:58:01.000000000 +0000 @@ -714,6 +714,11 @@ } else { // Otherwise, the queue contained exactly one element; we take the slow // path. + + // The barrier is required to prevent reordering the two reads of _age: + // one is the _age.get() below, and the other is _age.top() above the if-stmt. + // The algorithm may fail if _age.get() reads an older value than _age.top(). + OrderAccess::loadload(); return pop_local_slow(localBot, _age.get()); } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/workgroup.cpp openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/workgroup.cpp --- openjdk-8-8u232-b09/=unpacked-tar9=/src/share/vm/utilities/workgroup.cpp 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/src/share/vm/utilities/workgroup.cpp 2020-01-13 04:58:01.000000000 +0000 @@ -464,7 +464,6 @@ if (old == 0) { old = Atomic::cmpxchg(1, &_tasks[t], 0); } - assert(_tasks[t] == 1, "What else?"); bool res = old != 0; #ifdef ASSERT if (!res) { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESBase.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESBase.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESBase.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESBase.java 2020-01-13 04:58:01.000000000 +0000 @@ -29,6 +29,7 @@ import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.AlgorithmParameters; @@ -62,8 +63,12 @@ Random random = new Random(0); Cipher cipher; Cipher dCipher; - AlgorithmParameters algParams; + AlgorithmParameters algParams = null; SecretKey key; + GCMParameterSpec gcm_spec; + byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 }; + int tlen = 12; + byte[] iv = new byte[16]; static int numThreads = 0; int threadId; @@ -77,7 +82,10 @@ public void prepare() { try { - System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); + System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize ); if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 ) testingMisalignment = true; @@ -98,16 +106,24 @@ cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + // CBC init if (mode.equals("CBC")) { - int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0); - IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]); + IvParameterSpec initVector = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, key, initVector); - } else { algParams = cipher.getParameters(); + dCipher.init(Cipher.DECRYPT_MODE, key, initVector); + + // GCM init + } else if (mode.equals("GCM")) { + gcm_init(true); + gcm_init(false); + + // ECB init + } else { cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); } - algParams = cipher.getParameters(); - dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (threadId == 0) { childShowCipher(); } @@ -188,4 +204,19 @@ } abstract void childShowCipher(); + + void gcm_init(boolean encrypt) throws Exception { + gcm_spec = new GCMParameterSpec(tlen * 8, iv); + if (encrypt) { + // Get a new instance everytime because of reuse IV restrictions + cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE"); + cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec); + cipher.updateAAD(aad); + } else { + dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec); + dCipher.updateAAD(aad); + + + } + } } diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESDecode.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESDecode.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESDecode.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESDecode.java 2020-01-13 04:58:01.000000000 +0000 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(false); + } else if (!noReinit) { + dCipher.init(Cipher.DECRYPT_MODE, key, algParams); + } decode = new byte[decodeLength]; if (testingMisalignment) { int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESEncode.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESEncode.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESEncode.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESEncode.java 2020-01-13 04:58:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -32,7 +32,11 @@ @Override public void run() { try { - if (!noReinit) cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + if (mode.equals("GCM")) { + gcm_init(true); + } else if (!noReinit) { + cipher.init(Cipher.ENCRYPT_MODE, key, algParams); + } encode = new byte[encodeLength]; if (testingMisalignment) { int tempSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset); diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESMain.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESMain.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/7184394/TestAESMain.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/7184394/TestAESMain.java 2020-01-13 04:58:01.000000000 +0000 @@ -41,6 +41,13 @@ * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain * * @author Tom Deneau */ diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java 2020-01-13 04:58:01.000000000 +0000 @@ -22,9 +22,10 @@ */ import sun.hotspot.WhiteBox; -import sun.misc.Unsafe; import sun.misc.IOUtils; +import sun.misc.Unsafe; +import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; @@ -108,7 +109,13 @@ // (1) Load an anonymous version of this class using the corresponding Unsafe method URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class"); URLConnection connection = classUrl.openConnection(); - byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true); + + int length = connection.getContentLength(); + byte[] classBytes = IOUtils.readAllBytes(connection.getInputStream()); + if (length != -1 && classBytes.length != length) { + throw new IOException("Expected:" + length + ", actual: " + classBytes.length); + } + Class anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null); // (2) Make sure all paths of doWork are profiled and compiled diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/StrangeControl.jasm openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/StrangeControl.jasm --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/StrangeControl.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/StrangeControl.jasm 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class compiler/loopopts/StrangeControl + version 51:0 +{ + +static Field field:"I"; + +public static Method test:"(I)V" + stack 2 locals 2 +{ + iconst_0; + istore 1; + L1: stack_frame_type append; + locals_map int; + iinc 1, 1; + iload 1; + iconst_2; + if_icmple L1; + L2: stack_frame_type same; + iload_0; + putstatic Field field:"I"; + goto L1; +} + +} // end Class StrangeControl diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/superword/TestFuzzPreLoop.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/superword/TestFuzzPreLoop.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/superword/TestFuzzPreLoop.java 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8134739 8010500 + * @summary SEGV in SuperWord::get_pre_loop_end + * @run main/othervm compiler.loopopts.superword.TestFuzzPreLoop + */ + +package compiler.loopopts.superword; + +public class TestFuzzPreLoop { + static Object sink; + short sFld = -19206; + + void doTest() { + int[] arr = new int[400]; + + for (int i1 = 0; i1 < 200; i1++) { + for (int i2 = 0; i2 < 100; i2++) { + sink = new int[400]; + } + arr[i1] = 0; + } + + float f1 = 0; + for (int i3 = 0; i3 < 200; i3++) { + f1 += i3 * i3; + } + for (int i4 = 0; i4 < 200; i4++) { + f1 += i4 - sFld; + } + + System.out.println(arr); + System.out.println(f1); + } + + public static void main(String... args) throws Exception { + TestFuzzPreLoop test = new TestFuzzPreLoop(); + for (int i = 0; i < 100; i++) { + test.doTest(); + } + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/TestRemoveEmptyLoop.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/TestRemoveEmptyLoop.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/TestRemoveEmptyLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/TestRemoveEmptyLoop.java 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8231988 + * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation + * TestRemoveEmptyLoop + */ + +public class TestRemoveEmptyLoop { + + public void test() { + int i = 34; + for (; i > 0; i -= 11); + if (i < 0) { + // do nothing + } else { + throw new RuntimeException("Test failed."); + } + } + + public static void main(String[] args) { + TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop(); + for (int i = 0; i < 50000; i++) { + _instance.test(); + } + System.out.println("Test passed."); + } + +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/TestStrangeControl.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/TestStrangeControl.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/loopopts/TestStrangeControl.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/loopopts/TestStrangeControl.java 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8228888 + * @summary Test PhaseIdealLoop::has_local_phi_input() with phi input with non-dominating control. + * @compile StrangeControl.jasm + * @run main/othervm -Xbatch -XX:CompileCommand=inline,compiler.loopopts.StrangeControl::test + * compiler.loopopts.TestStrangeControl + */ + +package compiler.loopopts; + +public class TestStrangeControl { + + public static void main(String[] args) throws Exception { + Thread thread = new Thread() { + public void run() { + // Run this in an own thread because it's basically an endless loop + StrangeControl.test(42); + } + }; + thread.start(); + // Give thread executing strange control loop enough time to trigger OSR compilation + Thread.sleep(4000); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/print/TestProfileReturnTypePrinting.java openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/print/TestProfileReturnTypePrinting.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/compiler/print/TestProfileReturnTypePrinting.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/compiler/print/TestProfileReturnTypePrinting.java 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8073154 + * @build TestProfileReturnTypePrinting + * @run main/othervm -XX:TypeProfileLevel=020 + * -XX:CompileOnly=TestProfileReturnTypePrinting.testMethod + * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintLIR + * TestProfileReturnTypePrinting + * @summary Verify that c1's LIR that contains ProfileType node could be dumped + * without a crash disregard to an exact class knowledge. + */ +public class TestProfileReturnTypePrinting { + private static final int ITERATIONS = 1_000_000; + + public static void main(String args[]) { + for (int i = 0; i < ITERATIONS; i++) { + TestProfileReturnTypePrinting.testMethod(i); + } + } + + private static int testMethod(int i) { + return TestProfileReturnTypePrinting.foo().hashCode() + + TestProfileReturnTypePrinting.bar(i).hashCode(); + } + + /* Exact class of returned value is known statically. */ + private static B foo() { + return new B(); + } + + /* Exact class of returned value is not known statically. */ + private static Object bar(int i) { + if (i % 2 == 0) { + return new A(); + } else { + return new B(); + } + } + + private static class A { + } + + private static class B extends A { + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java openjdk-8-8u242-b08/=unpacked-tar9=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/gc/stress/gclocker/TestExcessGCLockerCollections.java 2020-01-13 04:58:01.000000000 +0000 @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package gc.stress.gclocker; + +// Based on Kim Barrett;s test for JDK-8048556 + +/* + * @test TestExcessGCLockerCollections + * @key gc + * @bug 8048556 + * @summary Check for GC Locker initiated GCs that immediately follow another + * GC and so have very little needing to be collected. + * @library /testlibrary + * @run driver/timeout=1000 gc.stress.gclocker.TestExcessGCLockerCollections 300 4 2 + */ + +import java.util.HashMap; +import java.util.Map; + +import java.util.zip.Deflater; + +import java.util.ArrayList; +import java.util.Arrays; + +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; +import java.lang.management.ManagementFactory; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import com.sun.management.GarbageCollectionNotificationInfo; +import com.sun.management.GcInfo; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +class TestExcessGCLockerCollectionsStringConstants { + // Some constant strings used in both GC logging and error detection + static public final String GCLOCKER_CAUSE = "GCLocker Initiated GC"; + static public final String USED_TOO_LOW = "TOO LOW"; + static public final String USED_OK = "OK"; +} + +class TestExcessGCLockerCollectionsAux { + static private final int LARGE_MAP_SIZE = 64 * 1024; + + static private final int MAP_ARRAY_LENGTH = 4; + static private final int MAP_SIZE = 1024; + + static private final int BYTE_ARRAY_LENGTH = 128 * 1024; + + static private void println(String str) { System.out.println(str); } + static private void println() { System.out.println(); } + + static private volatile boolean keepRunning = true; + + static Map populateMap(int size) { + Map map = new HashMap(); + for (int i = 0; i < size; i += 1) { + Integer keyInt = Integer.valueOf(i); + String valStr = "value is [" + i + "]"; + map.put(keyInt,valStr); + } + return map; + } + + static private class AllocatingWorker implements Runnable { + private final Object[] array = new Object[MAP_ARRAY_LENGTH]; + private int arrayIndex = 0; + + private void doStep() { + Map map = populateMap(MAP_SIZE); + array[arrayIndex] = map; + arrayIndex = (arrayIndex + 1) % MAP_ARRAY_LENGTH; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static private class JNICriticalWorker implements Runnable { + private int count; + + private void doStep() { + byte[] inputArray = new byte[BYTE_ARRAY_LENGTH]; + for (int i = 0; i < inputArray.length; i += 1) { + inputArray[i] = (byte) (count + i); + } + + Deflater deflater = new Deflater(); + deflater.setInput(inputArray); + deflater.finish(); + + byte[] outputArray = new byte[2 * inputArray.length]; + deflater.deflate(outputArray); + + count += 1; + } + + public void run() { + while (keepRunning) { + doStep(); + } + } + } + + static class GCNotificationListener implements NotificationListener { + static private final double MIN_USED_PERCENT = 40.0; + + static private final List newGenPoolNames = Arrays.asList( + "G1 Eden Space", // OpenJDK G1GC: -XX:+UseG1GC + "PS Eden Space", // OpenJDK ParallelGC: -XX:+ParallelGC + "Par Eden Space", // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC + "Eden Space" // OpenJDK SerialGC: -XX:+UseSerialGC + // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC -XX:-UseParNewGC + ); + + @Override + public void handleNotification(Notification notification, Object handback) { + try { + if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + GarbageCollectionNotificationInfo info = + GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + + String gc_cause = info.getGcCause(); + + if (gc_cause.equals(TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE)) { + Map memory_before_gc = info.getGcInfo().getMemoryUsageBeforeGc(); + + for (String newGenPoolName : newGenPoolNames) { + MemoryUsage usage = memory_before_gc.get(newGenPoolName); + if (usage == null) continue; + + double startTime = ((double) info.getGcInfo().getStartTime()) / 1000.0; + long used = usage.getUsed(); + long committed = usage.getCommitted(); + long max = usage.getMax(); + double used_percent = (((double) used) / Math.max(committed, max)) * 100.0; + + System.out.printf("%6.3f: (%s) %d/%d/%d, %8.4f%% (%s)\n", + startTime, gc_cause, used, committed, max, used_percent, + ((used_percent < MIN_USED_PERCENT) ? TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + : TestExcessGCLockerCollectionsStringConstants.USED_OK)); + } + } + } + } catch (RuntimeException ex) { + System.err.println("Exception during notification processing:" + ex); + ex.printStackTrace(); + } + } + + public static boolean register() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + + // Get the list of MX + List gc_mxbeans = ManagementFactory.getGarbageCollectorMXBeans(); + + // Create the notification listener + GCNotificationListener gcNotificationListener = new GCNotificationListener(); + + for (GarbageCollectorMXBean gcbean : gc_mxbeans) { + // Add notification listener for the MXBean + mbeanServer.addNotificationListener(gcbean.getObjectName(), gcNotificationListener, null, null); + } + } catch (Exception ex) { + System.err.println("Exception during mbean registration:" + ex); + ex.printStackTrace(); + // We've failed to set up, terminate + return false; + } + + return true; + } + } + + static public Map largeMap; + + static public void main(String args[]) { + long durationSec = Long.parseLong(args[0]); + int allocThreadNum = Integer.parseInt(args[1]); + int jniCriticalThreadNum = Integer.parseInt(args[2]); + + println("Running for " + durationSec + " secs"); + + if (!GCNotificationListener.register()) { + println("failed to register GC notification listener"); + System.exit(-1); + } + + largeMap = populateMap(LARGE_MAP_SIZE); + + println("Starting " + allocThreadNum + " allocating threads"); + for (int i = 0; i < allocThreadNum; i += 1) { + new Thread(new AllocatingWorker()).start(); + } + + println("Starting " + jniCriticalThreadNum + " jni critical threads"); + for (int i = 0; i < jniCriticalThreadNum; i += 1) { + new Thread(new JNICriticalWorker()).start(); + } + + long durationMS = (long) (1000 * durationSec); + long start = System.currentTimeMillis(); + long now = start; + long soFar = now - start; + while (soFar < durationMS) { + try { + Thread.sleep(durationMS - soFar); + } catch (Exception e) { + } + now = System.currentTimeMillis(); + soFar = now - start; + } + println("Done."); + keepRunning = false; + } +} + +public class TestExcessGCLockerCollections { + private static final String USED_OK_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_OK + "\\)"; + private static final String USED_TOO_LOW_LINE = + "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)" + + " .* " + + "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + "\\)"; + + private static final String[] COMMON_OPTIONS = new String[] { + "-Xmx1G", "-Xms1G", "-Xmn256M" }; + + public static void main(String args[]) throws Exception { + if (args.length < 3) { + System.out.println("usage: TestExcessGCLockerCollections" + + " " + + " "); + throw new RuntimeException("Invalid arguments"); + } + + ArrayList finalArgs = new ArrayList(); + finalArgs.addAll(Arrays.asList(COMMON_OPTIONS)); + finalArgs.add(TestExcessGCLockerCollectionsAux.class.getName()); + finalArgs.addAll(Arrays.asList(args)); + + // GC and other options obtained from test framework. + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + true, finalArgs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + //System.out.println("------------- begin stdout ----------------"); + //System.out.println(output.getStdout()); + //System.out.println("------------- end stdout ----------------"); + output.stdoutShouldMatch(USED_OK_LINE); + output.stdoutShouldNotMatch(USED_TOO_LOW_LINE); + } +} diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/test/runtime/8003720/VictimClassLoader.java openjdk-8-8u242-b08/=unpacked-tar9=/test/runtime/8003720/VictimClassLoader.java --- openjdk-8-8u232-b09/=unpacked-tar9=/test/runtime/8003720/VictimClassLoader.java 2019-09-26 06:17:41.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/test/runtime/8003720/VictimClassLoader.java 2020-01-13 04:58:01.000000000 +0000 @@ -22,6 +22,8 @@ * */ +import sun.misc.IOUtils; + public class VictimClassLoader extends ClassLoader { public static long counter = 0; @@ -72,8 +74,10 @@ } static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException { - // Warning here: - return sun.misc.IOUtils.readFully(in, len, true); + byte[] b = IOUtils.readAllBytes(in); + if (len != -1 && b.length != len) + throw new java.io.IOException("Expected:" + len + ", actual:" + b.length); + return b; } public void finalize() { diff -Nru openjdk-8-8u232-b09/=unpacked-tar9=/THIRD_PARTY_README openjdk-8-8u242-b08/=unpacked-tar9=/THIRD_PARTY_README --- openjdk-8-8u232-b09/=unpacked-tar9=/THIRD_PARTY_README 2019-10-16 00:44:38.000000000 +0000 +++ openjdk-8-8u242-b08/=unpacked-tar9=/THIRD_PARTY_README 2020-01-17 17:37:33.000000000 +0000 @@ -1334,11 +1334,13 @@ -------------------------------------------------------------------------------- -%% This notice is provided with respect to Joni v1.1.9, which may be +%% This notice is provided with respect to Joni v2.1.16, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- +Copyright (c) 2017 JRuby Team + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights