OpenJDK / amber / amber
changeset 60864:a0ee9f8c4511 pattern-runtime
Automatic merge with default
author | mcimadamore |
---|---|
date | Fri, 10 Apr 2020 17:10:22 +0000 |
parents | 652110767d97 95dcd21d36dc |
children | |
files | make/launcher/Launcher-jdk.rmic.gmk src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.inline.hpp src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacAppStore.entitlements src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacAppStore_Inherit.entitlements src/jdk.rmic/share/classes/module-info.java src/jdk.rmic/share/classes/sun/rmi/rmic/BatchEnvironment.java src/jdk.rmic/share/classes/sun/rmi/rmic/Constants.java src/jdk.rmic/share/classes/sun/rmi/rmic/Generator.java src/jdk.rmic/share/classes/sun/rmi/rmic/IndentingWriter.java src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java src/jdk.rmic/share/classes/sun/rmi/rmic/Names.java src/jdk.rmic/share/classes/sun/rmi/rmic/RMIConstants.java src/jdk.rmic/share/classes/sun/rmi/rmic/RMIGenerator.java src/jdk.rmic/share/classes/sun/rmi/rmic/RemoteClass.java src/jdk.rmic/share/classes/sun/rmi/rmic/Util.java src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic.properties src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_ja.properties src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_zh_CN.properties src/jdk.rmic/share/classes/sun/tools/asm/ArrayData.java src/jdk.rmic/share/classes/sun/tools/asm/Assembler.java src/jdk.rmic/share/classes/sun/tools/asm/CatchData.java src/jdk.rmic/share/classes/sun/tools/asm/ClassConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/ConstantPool.java src/jdk.rmic/share/classes/sun/tools/asm/ConstantPoolData.java src/jdk.rmic/share/classes/sun/tools/asm/Cover.java src/jdk.rmic/share/classes/sun/tools/asm/FieldConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/Instruction.java src/jdk.rmic/share/classes/sun/tools/asm/Label.java src/jdk.rmic/share/classes/sun/tools/asm/LocalVariable.java src/jdk.rmic/share/classes/sun/tools/asm/LocalVariableTable.java src/jdk.rmic/share/classes/sun/tools/asm/NameAndTypeConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/NameAndTypeData.java src/jdk.rmic/share/classes/sun/tools/asm/NumberConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/StringConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/StringExpressionConstantData.java src/jdk.rmic/share/classes/sun/tools/asm/SwitchData.java src/jdk.rmic/share/classes/sun/tools/asm/TryData.java src/jdk.rmic/share/classes/sun/tools/java/AmbiguousClass.java src/jdk.rmic/share/classes/sun/tools/java/AmbiguousMember.java src/jdk.rmic/share/classes/sun/tools/java/ArrayType.java src/jdk.rmic/share/classes/sun/tools/java/BinaryAttribute.java src/jdk.rmic/share/classes/sun/tools/java/BinaryClass.java src/jdk.rmic/share/classes/sun/tools/java/BinaryCode.java src/jdk.rmic/share/classes/sun/tools/java/BinaryConstantPool.java src/jdk.rmic/share/classes/sun/tools/java/BinaryExceptionHandler.java src/jdk.rmic/share/classes/sun/tools/java/BinaryMember.java src/jdk.rmic/share/classes/sun/tools/java/ClassDeclaration.java src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java src/jdk.rmic/share/classes/sun/tools/java/ClassFile.java src/jdk.rmic/share/classes/sun/tools/java/ClassNotFound.java src/jdk.rmic/share/classes/sun/tools/java/ClassPath.java src/jdk.rmic/share/classes/sun/tools/java/ClassType.java src/jdk.rmic/share/classes/sun/tools/java/CompilerError.java src/jdk.rmic/share/classes/sun/tools/java/Constants.java src/jdk.rmic/share/classes/sun/tools/java/Environment.java src/jdk.rmic/share/classes/sun/tools/java/FileClassFile.java src/jdk.rmic/share/classes/sun/tools/java/Identifier.java src/jdk.rmic/share/classes/sun/tools/java/IdentifierToken.java src/jdk.rmic/share/classes/sun/tools/java/Imports.java src/jdk.rmic/share/classes/sun/tools/java/MemberDefinition.java src/jdk.rmic/share/classes/sun/tools/java/MethodSet.java src/jdk.rmic/share/classes/sun/tools/java/MethodType.java src/jdk.rmic/share/classes/sun/tools/java/Package.java src/jdk.rmic/share/classes/sun/tools/java/Parser.java src/jdk.rmic/share/classes/sun/tools/java/ParserActions.java src/jdk.rmic/share/classes/sun/tools/java/PathClassFile.java src/jdk.rmic/share/classes/sun/tools/java/RuntimeConstants.java src/jdk.rmic/share/classes/sun/tools/java/Scanner.java src/jdk.rmic/share/classes/sun/tools/java/ScannerInputReader.java src/jdk.rmic/share/classes/sun/tools/java/SyntaxError.java src/jdk.rmic/share/classes/sun/tools/java/Type.java src/jdk.rmic/share/classes/sun/tools/java/ZipClassFile.java src/jdk.rmic/share/classes/sun/tools/javac/BatchEnvironment.java src/jdk.rmic/share/classes/sun/tools/javac/BatchParser.java src/jdk.rmic/share/classes/sun/tools/javac/CompilerMember.java src/jdk.rmic/share/classes/sun/tools/javac/ErrorConsumer.java src/jdk.rmic/share/classes/sun/tools/javac/ErrorMessage.java src/jdk.rmic/share/classes/sun/tools/javac/Main.java src/jdk.rmic/share/classes/sun/tools/javac/SourceClass.java src/jdk.rmic/share/classes/sun/tools/javac/SourceMember.java src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_ja.properties src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_zh_CN.properties src/jdk.rmic/share/classes/sun/tools/tree/AddExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AndExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ArrayAccessExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ArrayExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignAddExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignBitAndExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignBitOrExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignBitXorExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignDivideExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignMultiplyExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignOpExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignRemainderExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignShiftLeftExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignShiftRightExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignSubtractExpression.java src/jdk.rmic/share/classes/sun/tools/tree/AssignUnsignedShiftRightExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryArithmeticExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryAssignExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryBitExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryCompareExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryEqualityExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryLogicalExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BinaryShiftExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BitAndExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BitNotExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BitOrExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BitXorExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BooleanExpression.java src/jdk.rmic/share/classes/sun/tools/tree/BreakStatement.java src/jdk.rmic/share/classes/sun/tools/tree/ByteExpression.java src/jdk.rmic/share/classes/sun/tools/tree/CaseStatement.java src/jdk.rmic/share/classes/sun/tools/tree/CastExpression.java src/jdk.rmic/share/classes/sun/tools/tree/CatchStatement.java src/jdk.rmic/share/classes/sun/tools/tree/CharExpression.java src/jdk.rmic/share/classes/sun/tools/tree/CheckContext.java src/jdk.rmic/share/classes/sun/tools/tree/CodeContext.java src/jdk.rmic/share/classes/sun/tools/tree/CommaExpression.java src/jdk.rmic/share/classes/sun/tools/tree/CompoundStatement.java src/jdk.rmic/share/classes/sun/tools/tree/ConditionVars.java src/jdk.rmic/share/classes/sun/tools/tree/ConditionalExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ConstantExpression.java src/jdk.rmic/share/classes/sun/tools/tree/Context.java src/jdk.rmic/share/classes/sun/tools/tree/ContinueStatement.java src/jdk.rmic/share/classes/sun/tools/tree/ConvertExpression.java src/jdk.rmic/share/classes/sun/tools/tree/DeclarationStatement.java src/jdk.rmic/share/classes/sun/tools/tree/DivRemExpression.java src/jdk.rmic/share/classes/sun/tools/tree/DivideExpression.java src/jdk.rmic/share/classes/sun/tools/tree/DoStatement.java src/jdk.rmic/share/classes/sun/tools/tree/DoubleExpression.java src/jdk.rmic/share/classes/sun/tools/tree/EqualExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ExprExpression.java src/jdk.rmic/share/classes/sun/tools/tree/Expression.java src/jdk.rmic/share/classes/sun/tools/tree/ExpressionStatement.java src/jdk.rmic/share/classes/sun/tools/tree/FieldExpression.java src/jdk.rmic/share/classes/sun/tools/tree/FieldUpdater.java src/jdk.rmic/share/classes/sun/tools/tree/FinallyStatement.java src/jdk.rmic/share/classes/sun/tools/tree/FloatExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ForStatement.java src/jdk.rmic/share/classes/sun/tools/tree/GreaterExpression.java src/jdk.rmic/share/classes/sun/tools/tree/GreaterOrEqualExpression.java src/jdk.rmic/share/classes/sun/tools/tree/IdentifierExpression.java src/jdk.rmic/share/classes/sun/tools/tree/IfStatement.java src/jdk.rmic/share/classes/sun/tools/tree/IncDecExpression.java src/jdk.rmic/share/classes/sun/tools/tree/InlineMethodExpression.java src/jdk.rmic/share/classes/sun/tools/tree/InlineNewInstanceExpression.java src/jdk.rmic/share/classes/sun/tools/tree/InlineReturnStatement.java src/jdk.rmic/share/classes/sun/tools/tree/InstanceOfExpression.java src/jdk.rmic/share/classes/sun/tools/tree/IntExpression.java src/jdk.rmic/share/classes/sun/tools/tree/IntegerExpression.java src/jdk.rmic/share/classes/sun/tools/tree/LengthExpression.java src/jdk.rmic/share/classes/sun/tools/tree/LessExpression.java src/jdk.rmic/share/classes/sun/tools/tree/LessOrEqualExpression.java src/jdk.rmic/share/classes/sun/tools/tree/LocalMember.java src/jdk.rmic/share/classes/sun/tools/tree/LongExpression.java src/jdk.rmic/share/classes/sun/tools/tree/MethodExpression.java src/jdk.rmic/share/classes/sun/tools/tree/MultiplyExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NaryExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NegativeExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NewArrayExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NewInstanceExpression.java src/jdk.rmic/share/classes/sun/tools/tree/Node.java src/jdk.rmic/share/classes/sun/tools/tree/NotEqualExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NotExpression.java src/jdk.rmic/share/classes/sun/tools/tree/NullExpression.java src/jdk.rmic/share/classes/sun/tools/tree/OrExpression.java src/jdk.rmic/share/classes/sun/tools/tree/PositiveExpression.java src/jdk.rmic/share/classes/sun/tools/tree/PostDecExpression.java src/jdk.rmic/share/classes/sun/tools/tree/PostIncExpression.java src/jdk.rmic/share/classes/sun/tools/tree/PreDecExpression.java src/jdk.rmic/share/classes/sun/tools/tree/PreIncExpression.java src/jdk.rmic/share/classes/sun/tools/tree/RemainderExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ReturnStatement.java src/jdk.rmic/share/classes/sun/tools/tree/ShiftLeftExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ShiftRightExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ShortExpression.java src/jdk.rmic/share/classes/sun/tools/tree/Statement.java src/jdk.rmic/share/classes/sun/tools/tree/StringExpression.java src/jdk.rmic/share/classes/sun/tools/tree/SubtractExpression.java src/jdk.rmic/share/classes/sun/tools/tree/SuperExpression.java src/jdk.rmic/share/classes/sun/tools/tree/SwitchStatement.java src/jdk.rmic/share/classes/sun/tools/tree/SynchronizedStatement.java src/jdk.rmic/share/classes/sun/tools/tree/ThisExpression.java src/jdk.rmic/share/classes/sun/tools/tree/ThrowStatement.java src/jdk.rmic/share/classes/sun/tools/tree/TryStatement.java src/jdk.rmic/share/classes/sun/tools/tree/TypeExpression.java src/jdk.rmic/share/classes/sun/tools/tree/UnaryExpression.java src/jdk.rmic/share/classes/sun/tools/tree/UnsignedShiftRightExpression.java src/jdk.rmic/share/classes/sun/tools/tree/UplevelReference.java src/jdk.rmic/share/classes/sun/tools/tree/VarDeclarationStatement.java src/jdk.rmic/share/classes/sun/tools/tree/Vset.java src/jdk.rmic/share/classes/sun/tools/tree/WhileStatement.java src/jdk.rmic/share/classes/sun/tools/util/CommandLine.java src/jdk.rmic/share/classes/sun/tools/util/ModifierFilter.java src/jdk.rmic/share/man/rmic.1 test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMBean/findMonitorDeadlockedThreads/find001.java test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMBean/isCurrentThreadCpuTimeSupported/curthcputime001.java test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMBean/isThreadContentionMonitoringSupported/thcontmonitor001.java test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMBean/isThreadCpuTimeSupported/thcputime001.java test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMBean/resetPeakThreadCount/reset001.java test/jdk/sun/rmi/rmic/RMIGenerator/RmicDefault.java test/jdk/sun/rmi/rmic/RMIGenerator/packagedir/AppletServer.java test/jdk/sun/rmi/rmic/RMIGenerator/packagedir/RmicMeImpl.java test/jdk/sun/rmi/rmic/RMIGenerator/packagedir/RmicMeInterface.java test/jdk/sun/rmi/rmic/classFileVersion/G1.java test/jdk/sun/rmi/rmic/classFileVersion/G1Impl.java test/jdk/sun/rmi/rmic/classFileVersion/run.sh test/jdk/sun/rmi/rmic/classpath/RMICClassPathTest.java test/jdk/sun/rmi/rmic/covariantReturns/G2.java test/jdk/sun/rmi/rmic/covariantReturns/G2Impl.java test/jdk/sun/rmi/rmic/covariantReturns/G5.java test/jdk/sun/rmi/rmic/covariantReturns/G5Impl.java test/jdk/sun/rmi/rmic/covariantReturns/run.sh test/jdk/sun/rmi/rmic/defaultStubVersion/G1.java test/jdk/sun/rmi/rmic/defaultStubVersion/G1Impl.java test/jdk/sun/rmi/rmic/defaultStubVersion/run.sh test/jdk/sun/rmi/rmic/extraCompilation/run.sh test/jdk/sun/rmi/rmic/manifestClassPath/Util.sh test/jdk/sun/rmi/rmic/manifestClassPath/run.sh test/jdk/sun/rmi/rmic/minimizeWrapperInstances/P.java test/jdk/sun/rmi/rmic/minimizeWrapperInstances/PImpl.java test/jdk/sun/rmi/rmic/minimizeWrapperInstances/Test.java test/jdk/sun/rmi/rmic/minimizeWrapperInstances/run.sh test/jdk/sun/rmi/rmic/oldjavacRemoved/Foo.java test/jdk/sun/rmi/rmic/oldjavacRemoved/sunToolsJavacMain.sh test/jdk/sun/tools/java/CFCTest.java |
diffstat | 591 files changed, 5565 insertions(+), 52608 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Apr 07 18:30:32 2020 +0000 +++ b/.hgtags Fri Apr 10 17:10:22 2020 +0000 @@ -628,3 +628,4 @@ 82b7c62cf4cc56828a8fb724f57087967232a2a7 jdk-15+15 5c7ec21f5d13f6eb5cd32288c69b8be2f9cac256 jdk-15+16 dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17 +44aef192b488a48cce12422394691a6b1d16b98e jdk-15+18
--- a/make/CompileJavaModules.gmk Tue Apr 07 18:30:32 2020 +0000 +++ b/make/CompileJavaModules.gmk Fri Apr 10 17:10:22 2020 +0000 @@ -351,11 +351,6 @@ ################################################################################ -jdk.rmic_DISABLED_WARNINGS += deprecation -jdk.rmic_CLEAN += .properties - -################################################################################ - # No SCTP implementation on Mac OS X or AIX. These classes should be excluded. SCTP_IMPL_CLASSES = \ $(TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/AssociationChange.java \
--- a/make/common/Modules.gmk Tue Apr 07 18:30:32 2020 +0000 +++ b/make/common/Modules.gmk Fri Apr 10 17:10:22 2020 +0000 @@ -172,7 +172,6 @@ jdk.naming.rmi \ jdk.net \ jdk.nio.mapmode \ - jdk.rmic \ jdk.scripting.nashorn \ jdk.sctp \ jdk.security.auth \
--- a/make/data/lsrdata/language-subtag-registry.txt Tue Apr 07 18:30:32 2020 +0000 +++ b/make/data/lsrdata/language-subtag-registry.txt Fri Apr 10 17:10:22 2020 +0000 @@ -1,4 +1,4 @@ -File-Date: 2020-03-16 +File-Date: 2020-04-01 %% Type: language Subtag: aa @@ -1530,7 +1530,7 @@ %% Type: language Subtag: adb -Description: Adabe +Description: Atauran Added: 2009-07-29 %% Type: language @@ -2707,6 +2707,7 @@ Subtag: aoh Description: Arma Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: aoi @@ -3770,6 +3771,7 @@ Subtag: ayy Description: Tayabas Ayta Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: ayz @@ -4085,6 +4087,7 @@ Subtag: bbz Description: Babalia Creole Arabic Added: 2009-07-29 +Deprecated: 2020-03-28 Macrolanguage: ar %% Type: language @@ -5755,6 +5758,7 @@ Subtag: bpb Description: Barbacoas Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: bpd @@ -6011,7 +6015,7 @@ %% Type: language Subtag: brf -Description: Bera +Description: Bira Added: 2009-07-29 %% Type: language @@ -7374,6 +7378,7 @@ Subtag: cca Description: Cauca Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: ccc @@ -7480,6 +7485,7 @@ Subtag: cdg Description: Chamari Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: cdh @@ -7875,6 +7881,11 @@ Added: 2009-07-29 %% Type: language +Subtag: ckm +Description: Chakavian +Added: 2020-03-28 +%% +Type: language Subtag: ckn Description: Kaang Chin Added: 2013-09-10 @@ -8121,6 +8132,13 @@ Added: 2009-07-29 %% Type: language +Subtag: cnp +Description: Northern Ping Chinese +Description: Northern Pinghua +Added: 2020-03-28 +Macrolanguage: zh +%% +Type: language Subtag: cnr Description: Montenegrin Added: 2018-01-23 @@ -8564,6 +8582,13 @@ Added: 2009-07-29 %% Type: language +Subtag: csp +Description: Southern Ping Chinese +Description: Southern Pinghua +Added: 2020-03-28 +Macrolanguage: zh +%% +Type: language Subtag: csq Description: Croatia Sign Language Added: 2009-07-29 @@ -9318,6 +9343,7 @@ Type: language Subtag: dgr Description: Dogrib +Description: Tłı̨chǫ Added: 2005-10-16 %% Type: language @@ -9334,6 +9360,7 @@ Subtag: dgu Description: Degaru Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: dgw @@ -9720,6 +9747,11 @@ Added: 2009-07-29 %% Type: language +Subtag: dmf +Description: Medefaidrin +Added: 2020-03-28 +%% +Type: language Subtag: dmg Description: Upper Kinabatangan Added: 2009-07-29 @@ -10041,6 +10073,8 @@ Subtag: drr Description: Dororo Added: 2009-07-29 +Deprecated: 2020-03-28 +Preferred-Value: kzk %% Type: language Subtag: drs @@ -10330,6 +10364,11 @@ Added: 2009-07-29 %% Type: language +Subtag: dwk +Description: Dawik Kui +Added: 2020-03-28 +%% +Type: language Subtag: dwl Description: Walo Kumbe Dogon Added: 2009-07-29 @@ -10455,6 +10494,11 @@ Added: 2013-09-10 %% Type: language +Subtag: ebc +Description: Beginci +Added: 2020-03-28 +%% +Type: language Subtag: ebg Description: Ebughu Added: 2009-07-29 @@ -10576,6 +10620,7 @@ Subtag: ekc Description: Eastern Karnic Added: 2013-09-10 +Deprecated: 2020-03-28 %% Type: language Subtag: eke @@ -11881,6 +11926,7 @@ Type: language Subtag: gdh Description: Gadjerawang +Description: Gajirrabeng Added: 2009-07-29 %% Type: language @@ -11970,6 +12016,11 @@ Added: 2009-07-29 %% Type: language +Subtag: gef +Description: Gerai +Added: 2020-03-28 +%% +Type: language Subtag: geg Description: Gengle Added: 2009-07-29 @@ -12381,6 +12432,8 @@ Subtag: gli Description: Guliguli Added: 2009-07-29 +Deprecated: 2020-03-28 +Preferred-Value: kzk %% Type: language Subtag: glj @@ -12481,6 +12534,12 @@ Added: 2009-07-29 %% Type: language +Subtag: gmr +Description: Mirning +Description: Mirniny +Added: 2020-03-28 +%% +Type: language Subtag: gmv Description: Gamo Added: 2009-07-29 @@ -13155,6 +13214,7 @@ %% Type: language Subtag: gwc +Description: Gawri Description: Kalami Added: 2009-07-29 %% @@ -13859,6 +13919,11 @@ Added: 2009-07-29 %% Type: language +Subtag: hng +Description: Hungu +Added: 2020-03-28 +%% +Type: language Subtag: hnh Description: ǁAni Added: 2009-07-29 @@ -14140,6 +14205,7 @@ Type: language Subtag: huc Description: ǂHua +Description: ǂʼAmkhoe Added: 2009-07-29 %% Type: language @@ -15910,6 +15976,7 @@ Type: language Subtag: kaa Description: Kara-Kalpak +Description: Karakalpak Added: 2005-10-16 %% Type: language @@ -17067,8 +17134,9 @@ %% Type: language Subtag: kjf -Description: Khalaj -Added: 2009-07-29 +Description: Khalaj [Indo-Iranian] +Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: kjg @@ -17248,7 +17316,7 @@ %% Type: language Subtag: kkq -Description: Kaiku +Description: Kaeku Added: 2009-07-29 %% Type: language @@ -17344,7 +17412,7 @@ %% Type: language Subtag: klj -Description: Turkic Khalaj +Description: Khalaj Added: 2009-07-29 %% Type: language @@ -18497,6 +18565,7 @@ Type: language Subtag: kui Description: Kuikúro-Kalapálo +Description: Kalapalo Added: 2009-07-29 %% Type: language @@ -18908,6 +18977,8 @@ Subtag: kxl Description: Nepali Kurux Added: 2009-07-29 +Deprecated: 2020-03-28 +Preferred-Value: kru %% Type: language Subtag: kxm @@ -18953,6 +19024,8 @@ Subtag: kxu Description: Kui (India) Added: 2009-07-29 +Deprecated: 2020-03-28 +Comments: see dwk, uki %% Type: language Subtag: kxv @@ -20337,6 +20410,7 @@ Subtag: lmz Description: Lumbee Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: lna @@ -22788,6 +22862,7 @@ %% Type: language Subtag: moe +Description: Innu Description: Montagnais Added: 2009-07-29 %% @@ -26199,6 +26274,11 @@ Added: 2009-07-29 %% Type: language +Subtag: nsb +Description: Lower Nossob +Added: 2020-03-28 +%% +Type: language Subtag: nsc Description: Nshi Added: 2009-07-29 @@ -26667,6 +26747,8 @@ Subtag: nxu Description: Narau Added: 2009-07-29 +Deprecated: 2020-03-28 +Preferred-Value: bpp %% Type: language Subtag: nxx @@ -28166,7 +28248,7 @@ %% Type: language Subtag: pfe -Description: Peere +Description: Pere Added: 2009-07-29 %% Type: language @@ -28572,6 +28654,7 @@ Subtag: plp Description: Palpa Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: plq @@ -31132,6 +31215,8 @@ Subtag: sdm Description: Semandang Added: 2009-07-29 +Deprecated: 2020-03-28 +Comments: see ebc, gef, sdq %% Type: language Subtag: sdn @@ -31150,6 +31235,11 @@ Added: 2009-07-29 %% Type: language +Subtag: sdq +Description: Semandang +Added: 2020-03-28 +%% +Type: language Subtag: sdr Description: Oraon Sadri Added: 2009-07-29 @@ -33502,6 +33592,7 @@ Subtag: tbb Description: Tapeba Added: 2009-07-29 +Deprecated: 2020-03-28 %% Type: language Subtag: tbc @@ -36240,6 +36331,11 @@ Added: 2009-07-29 %% Type: language +Subtag: uki +Description: Kui (India) +Added: 2020-03-28 +%% +Type: language Subtag: ukk Description: Muak Sa-aak Added: 2017-02-23 @@ -36271,6 +36367,11 @@ Added: 2009-07-29 %% Type: language +Subtag: ukv +Description: Kuku +Added: 2020-03-28 +%% +Type: language Subtag: ukw Description: Ukwuani-Aboh-Ndoni Added: 2009-07-29 @@ -37760,6 +37861,11 @@ Added: 2009-07-29 %% Type: language +Subtag: wlh +Description: Welaun +Added: 2020-03-28 +%% +Type: language Subtag: wli Description: Waioli Added: 2009-07-29 @@ -39232,6 +39338,11 @@ Added: 2013-09-10 %% Type: language +Subtag: xnm +Description: Ngumbarl +Added: 2020-03-28 +%% +Type: language Subtag: xnn Description: Northern Kankanay Added: 2009-07-29 @@ -39334,22 +39445,45 @@ Added: 2013-09-10 %% Type: language +Subtag: xpb +Description: Northeastern Tasmanian +Description: Pyemmairrener +Added: 2020-03-28 +%% +Type: language Subtag: xpc Description: Pecheneg Added: 2009-07-29 %% Type: language +Subtag: xpd +Description: Oyster Bay Tasmanian +Added: 2020-03-28 +%% +Type: language Subtag: xpe Description: Liberia Kpelle Added: 2009-07-29 Macrolanguage: kpe %% Type: language +Subtag: xpf +Description: Southeast Tasmanian +Description: Nuenonne +Added: 2020-03-28 +%% +Type: language Subtag: xpg Description: Phrygian Added: 2009-07-29 %% Type: language +Subtag: xph +Description: North Midlands Tasmanian +Description: Tyerrenoterpanner +Added: 2020-03-28 +%% +Type: language Subtag: xpi Description: Pictish Added: 2009-07-29 @@ -39365,6 +39499,11 @@ Added: 2009-07-29 %% Type: language +Subtag: xpl +Description: Port Sorell Tasmanian +Added: 2020-03-28 +%% +Type: language Subtag: xpm Description: Pumpokol Added: 2009-07-29 @@ -39410,11 +39549,34 @@ Added: 2009-07-29 %% Type: language +Subtag: xpv +Description: Northern Tasmanian +Description: Tommeginne +Added: 2020-03-28 +%% +Type: language +Subtag: xpw +Description: Northwestern Tasmanian +Description: Peerapper +Added: 2020-03-28 +%% +Type: language +Subtag: xpx +Description: Southwestern Tasmanian +Description: Toogee +Added: 2020-03-28 +%% +Type: language Subtag: xpy Description: Puyo Added: 2009-07-29 %% Type: language +Subtag: xpz +Description: Bruny Island Tasmanian +Added: 2020-03-28 +%% +Type: language Subtag: xqa Description: Karakhanid Added: 2009-07-29 @@ -39468,6 +39630,8 @@ Subtag: xrq Description: Karranga Added: 2013-09-10 +Deprecated: 2020-03-28 +Preferred-Value: dmw %% Type: language Subtag: xrr @@ -39700,6 +39864,8 @@ Subtag: xtz Description: Tasmanian Added: 2009-07-29 +Deprecated: 2020-03-28 +Comments: see xpb, xpd, xpf, xph, xpl, xpv, xpw, xpx, xpz %% Type: language Subtag: xua @@ -39729,6 +39895,7 @@ Type: language Subtag: xul Description: Ngunawal +Description: Nunukul Added: 2013-09-10 %% Type: language @@ -41321,6 +41488,11 @@ Added: 2009-07-29 %% Type: language +Subtag: zba +Description: Balaibalan +Added: 2020-03-28 +%% +Type: language Subtag: zbc Description: Central Berawan Added: 2009-07-29 @@ -41486,6 +41658,8 @@ Subtag: zir Description: Ziriya Added: 2009-07-29 +Deprecated: 2020-03-28 +Preferred-Value: scv %% Type: language Subtag: ziw @@ -42463,6 +42637,7 @@ Subtag: bbz Description: Babalia Creole Arabic Added: 2009-07-29 +Deprecated: 2020-03-28 Preferred-Value: bbz Prefix: ar Macrolanguage: ar @@ -42580,6 +42755,15 @@ Macrolanguage: zh %% Type: extlang +Subtag: cnp +Description: Northern Ping Chinese +Description: Northern Pinghua +Added: 2020-03-28 +Preferred-Value: cnp +Prefix: zh +Macrolanguage: zh +%% +Type: extlang Subtag: coa Description: Cocos Islands Malay Added: 2009-07-29 @@ -42647,6 +42831,15 @@ Prefix: sgn %% Type: extlang +Subtag: csp +Description: Southern Ping Chinese +Description: Southern Pinghua +Added: 2020-03-28 +Preferred-Value: csp +Prefix: zh +Macrolanguage: zh +%% +Type: extlang Subtag: csq Description: Croatia Sign Language Added: 2009-07-29 @@ -46630,6 +46823,12 @@ Letras in 1943 and generally used in Brazil until 2009 %% Type: variant +Subtag: akuapem +Description: Akuapem Twi +Added: 2017-06-05 +Prefix: tw +%% +Type: variant Subtag: alalc97 Description: ALA-LC Romanization, 1997 edition Added: 2009-12-09 @@ -46648,12 +46847,6 @@ continuum in Eastern Suriname and Western French Guiana %% Type: variant -Subtag: akuapem -Description: Akuapem Twi -Added: 2017-06-05 -Prefix: tw -%% -Type: variant Subtag: ao1990 Description: Portuguese Language Orthographic Agreement of 1990 (Acordo Ortográfico da Língua Portuguesa de 1990)
--- a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java Tue Apr 07 18:30:32 2020 +0000 +++ b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java Fri Apr 10 17:10:22 2020 +0000 @@ -33,10 +33,12 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TreeMap; +import java.util.stream.Collectors; /** * This tool reads the IANA Language Subtag Registry data file downloaded from @@ -75,32 +77,49 @@ String type = null; String tag = null; String preferred = null; + String prefix = null; for (String line : Files.readAllLines(Paths.get(filename), Charset.forName("UTF-8"))) { line = line.toLowerCase(Locale.ROOT); - int index = line.indexOf(' ')+1; + int index = line.indexOf(' ') + 1; if (line.startsWith("file-date:")) { LSRrevisionDate = line.substring(index); } else if (line.startsWith("type:")) { type = line.substring(index); } else if (line.startsWith("tag:") || line.startsWith("subtag:")) { tag = line.substring(index); - } else if (line.startsWith("preferred-value:") - && !type.equals("extlang")) { + } else if (line.startsWith("preferred-value:")) { preferred = line.substring(index); - processDeprecatedData(type, tag, preferred); + } else if (line.startsWith("prefix:")) { + prefix = line.substring(index); } else if (line.equals("%%")) { + processDeprecatedData(type, tag, preferred, prefix); type = null; tag = null; + preferred = null; + prefix = null; } } + + // Last entry + processDeprecatedData(type, tag, preferred, prefix); } private static void processDeprecatedData(String type, String tag, - String preferred) { + String preferred, + String prefix) { StringBuilder sb; + + if (type == null || tag == null || preferred == null) { + return; + } + + if (type.equals("extlang") && prefix != null) { + tag = prefix + "-" + tag; + } + if (type.equals("region") || type.equals("variant")) { if (!initialRegionVariantMap.containsKey(preferred)) { sb = new StringBuilder("-"); @@ -113,7 +132,7 @@ + " A region/variant subtag \"" + preferred + "\" is registered for more than one subtags."); } - } else { // language, grandfahered, and redundant + } else { // language, extlang, grandfathered, and redundant if (!initialLanguageMap.containsKey(preferred)) { sb = new StringBuilder(preferred); sb.append(','); @@ -131,7 +150,12 @@ private static void generateEquivalentMap() { String[] subtags; for (String preferred : initialLanguageMap.keySet()) { - subtags = initialLanguageMap.get(preferred).toString().split(","); + // There are cases where the same tag may appear in two entries, e.g., + // "yue" is defined both as extlang and redundant. Remove the dup. + subtags = Arrays.stream(initialLanguageMap.get(preferred).toString().split(",")) + .distinct() + .collect(Collectors.toList()) + .toArray(new String[0]); if (subtags.length == 2) { sortedLanguageMap1.put(subtags[0], subtags[1]);
--- a/make/launcher/Launcher-jdk.rmic.gmk Tue Apr 07 18:30:32 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# Copyright (c) 2011, 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. 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. -# - -include LauncherCommon.gmk - -$(eval $(call SetupBuildLauncher, rmic, \ - MAIN_CLASS := sun.rmi.rmic.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ -))
--- a/make/nashorn/element-list Tue Apr 07 18:30:32 2020 +0000 +++ b/make/nashorn/element-list Fri Apr 10 17:10:22 2020 +0000 @@ -260,7 +260,6 @@ module:jdk.net jdk.net jdk.nio -module:jdk.rmic module:jdk.scripting.nashorn jdk.nashorn.api.scripting jdk.nashorn.api.tree
--- a/src/hotspot/cpu/aarch64/aarch64.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Fri Apr 10 17:10:22 2020 +0000 @@ -1027,6 +1027,13 @@ } }; +class Node::PD { +public: + enum NodeFlags { + _last_flag = Node::_last_flag + }; +}; + bool is_CAS(int opcode, bool maybe_volatile); // predicates controlling emit of ldr<x>/ldar<x> and associated dmb @@ -1051,6 +1058,17 @@ // Derived RegMask with conditionally allocatable registers + void PhaseOutput::pd_perform_mach_node_analysis() { + } + + int MachNode::pd_alignment_required() const { + return 1; + } + + int MachNode::compute_padding(int current_offset) const { + return 0; + } + RegMask _ANY_REG32_mask; RegMask _ANY_REG_mask; RegMask _PTR_REG_mask; @@ -2349,10 +2367,19 @@ const bool Matcher::convi2l_type_required = false; +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) + mstack.push(m, Visit); // m = ShiftCntV + return true; + } + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { if (clone_base_plus_offset_address(m, mstack, address_visited)) { return true; } @@ -16013,14 +16040,14 @@ effect(TEMP tmp, TEMP tmp2); format %{ "umov $tmp, $src2, S, 0\n\t" "umov $tmp2, $src2, S, 1\n\t" - "addw $dst, $src1, $tmp\n\t" - "addw $dst, $dst, $tmp2\t add reduction2i" + "addw $tmp, $src1, $tmp\n\t" + "addw $dst, $tmp, $tmp2\t# add reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); - __ addw($dst$$Register, $src1$$Register, $tmp$$Register); - __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); + __ addw($tmp$$Register, $src1$$Register, $tmp$$Register); + __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); %} ins_pipe(pipe_class_default); %} @@ -16032,7 +16059,7 @@ effect(TEMP tmp, TEMP tmp2); format %{ "addv $tmp, T4S, $src2\n\t" "umov $tmp2, $tmp, S, 0\n\t" - "addw $dst, $tmp2, $src1\t add reduction4i" + "addw $dst, $tmp2, $src1\t# add reduction4I" %} ins_encode %{ __ addv(as_FloatRegister($tmp$$reg), __ T4S, @@ -16051,7 +16078,7 @@ format %{ "umov $tmp, $src2, S, 0\n\t" "mul $dst, $tmp, $src1\n\t" "umov $tmp, $src2, S, 1\n\t" - "mul $dst, $tmp, $dst\t mul reduction2i\n\t" + "mul $dst, $tmp, $dst\t# mul reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); @@ -16072,7 +16099,7 @@ "umov $tmp2, $tmp, S, 0\n\t" "mul $dst, $tmp2, $src1\n\t" "umov $tmp2, $tmp, S, 1\n\t" - "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" + "mul $dst, $tmp2, $dst\t# mul reduction4I" %} ins_encode %{ __ ins(as_FloatRegister($tmp$$reg), __ D, @@ -16094,7 +16121,7 @@ effect(TEMP tmp, TEMP dst); format %{ "fadds $dst, $src1, $src2\n\t" "ins $tmp, S, $src2, 0, 1\n\t" - "fadds $dst, $dst, $tmp\t add reduction2f" + "fadds $dst, $dst, $tmp\t# add reduction2F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), @@ -16118,7 +16145,7 @@ "ins $tmp, S, $src2, 0, 2\n\t" "fadds $dst, $dst, $tmp\n\t" "ins $tmp, S, $src2, 0, 3\n\t" - "fadds $dst, $dst, $tmp\t add reduction4f" + "fadds $dst, $dst, $tmp\t# add reduction4F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), @@ -16146,7 +16173,7 @@ effect(TEMP tmp, TEMP dst); format %{ "fmuls $dst, $src1, $src2\n\t" "ins $tmp, S, $src2, 0, 1\n\t" - "fmuls $dst, $dst, $tmp\t add reduction4f" + "fmuls $dst, $dst, $tmp\t# mul reduction2F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), @@ -16170,7 +16197,7 @@ "ins $tmp, S, $src2, 0, 2\n\t" "fmuls $dst, $dst, $tmp\n\t" "ins $tmp, S, $src2, 0, 3\n\t" - "fmuls $dst, $dst, $tmp\t add reduction4f" + "fmuls $dst, $dst, $tmp\t# mul reduction4F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), @@ -16198,7 +16225,7 @@ effect(TEMP tmp, TEMP dst); format %{ "faddd $dst, $src1, $src2\n\t" "ins $tmp, D, $src2, 0, 1\n\t" - "faddd $dst, $dst, $tmp\t add reduction2d" + "faddd $dst, $dst, $tmp\t# add reduction2D" %} ins_encode %{ __ faddd(as_FloatRegister($dst$$reg), @@ -16218,7 +16245,7 @@ effect(TEMP tmp, TEMP dst); format %{ "fmuld $dst, $src1, $src2\n\t" "ins $tmp, D, $src2, 0, 1\n\t" - "fmuld $dst, $dst, $tmp\t add reduction2d" + "fmuld $dst, $dst, $tmp\t# mul reduction2D" %} ins_encode %{ __ fmuld(as_FloatRegister($dst$$reg), @@ -16238,7 +16265,7 @@ effect(TEMP_DEF dst, TEMP tmp); format %{ "fmaxs $dst, $src1, $src2\n\t" "ins $tmp, S, $src2, 0, 1\n\t" - "fmaxs $dst, $dst, $tmp\t max reduction2F" %} + "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} ins_encode %{ __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); @@ -16253,7 +16280,7 @@ ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fmaxv $dst, T4S, $src2\n\t" - "fmaxs $dst, $dst, $src1\t max reduction4F" %} + "fmaxs $dst, $dst, $src1\t# max reduction4F" %} ins_encode %{ __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); @@ -16268,7 +16295,7 @@ effect(TEMP_DEF dst, TEMP tmp); format %{ "fmaxd $dst, $src1, $src2\n\t" "ins $tmp, D, $src2, 0, 1\n\t" - "fmaxd $dst, $dst, $tmp\t max reduction2D" %} + "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} ins_encode %{ __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); @@ -16284,7 +16311,7 @@ effect(TEMP_DEF dst, TEMP tmp); format %{ "fmins $dst, $src1, $src2\n\t" "ins $tmp, S, $src2, 0, 1\n\t" - "fmins $dst, $dst, $tmp\t min reduction2F" %} + "fmins $dst, $dst, $tmp\t# min reduction2F" %} ins_encode %{ __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); @@ -16299,7 +16326,7 @@ ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fminv $dst, T4S, $src2\n\t" - "fmins $dst, $dst, $src1\t min reduction4F" %} + "fmins $dst, $dst, $src1\t# min reduction4F" %} ins_encode %{ __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); @@ -16314,7 +16341,7 @@ effect(TEMP_DEF dst, TEMP tmp); format %{ "fmind $dst, $src1, $src2\n\t" "ins $tmp, D, $src2, 0, 1\n\t" - "fmind $dst, $dst, $tmp\t min reduction2D" %} + "fmind $dst, $dst, $tmp\t# min reduction2D" %} ins_encode %{ __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1);
--- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,18 @@ Register addr, Register count, RegSet saved_regs) { bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0; if (!dest_uninitialized) { + Label done; + Address in_progress(rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset())); + + // Is marking active? + if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { + __ ldrw(rscratch1, in_progress); + } else { + assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); + __ ldrb(rscratch1, in_progress); + } + __ cbzw(rscratch1, done); + __ push(saved_regs, sp); if (count == c_rarg0) { if (addr == c_rarg1) { @@ -68,6 +80,8 @@ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_oop_entry), 2); } __ pop(saved_regs, sp); + + __ bind(done); } }
--- a/src/hotspot/cpu/arm/arm.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/arm/arm.ad Fri Apr 10 17:10:22 2020 +0000 @@ -116,6 +116,13 @@ }; +class Node::PD { +public: + enum NodeFlags { + _last_flag = Node::_last_flag + }; +}; + %} source %{ @@ -124,6 +131,16 @@ static FloatRegister reg_to_FloatRegister_object(int register_encoding); static Register reg_to_register_object(int register_encoding); +void PhaseOutput::pd_perform_mach_node_analysis() { +} + +int MachNode::pd_alignment_required() const { + return 1; +} + +int MachNode::compute_padding(int current_offset) const { + return 0; +} // **************************************************************************** @@ -1085,10 +1102,19 @@ return false; } +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) + mstack.push(m, Visit); // m = ShiftCntV + return true; + } + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { return clone_base_plus_offset_address(m, mstack, address_visited); }
--- a/src/hotspot/cpu/ppc/ppc.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/ppc/ppc.ad Fri Apr 10 17:10:22 2020 +0000 @@ -982,10 +982,26 @@ source %{ +void PhaseOutput::pd_perform_mach_node_analysis() { +} + +int MachNode::pd_alignment_required() const { + return 1; +} + +int MachNode::compute_padding(int current_offset) const { + return 0; +} + +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { return clone_base_plus_offset_address(m, mstack, address_visited); } @@ -2164,6 +2180,13 @@ }; +class Node::PD { +public: + enum NodeFlags { + _last_flag = Node::_last_flag + }; +}; + %} // end source_hpp source %{
--- a/src/hotspot/cpu/s390/s390.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/s390/s390.ad Fri Apr 10 17:10:22 2020 +0000 @@ -605,6 +605,17 @@ // from the start of the call to the point where the return address // will point. +void PhaseOutput::pd_perform_mach_node_analysis() { +} + +int MachNode::pd_alignment_required() const { + return 1; +} + +int MachNode::compute_padding(int current_offset) const { + return 0; +} + int MachCallStaticJavaNode::ret_addr_offset() { if (_method) { return 8; @@ -1423,6 +1434,13 @@ } }; +class Node::PD { +public: + enum NodeFlags { + _last_flag = Node::_last_flag + }; +}; + %} // end source_hpp section source %{ @@ -1793,10 +1811,15 @@ const bool Matcher::convi2l_type_required = true; +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { return clone_base_plus_offset_address(m, mstack, address_visited); }
--- a/src/hotspot/cpu/sparc/sparc.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/sparc/sparc.ad Fri Apr 10 17:10:22 2020 +0000 @@ -471,6 +471,13 @@ } }; +class Node::PD { +public: + enum NodeFlags { + _last_flag = Node::_last_flag + }; +}; + %} source %{ @@ -483,6 +490,17 @@ static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding); static Register reg_to_register_object(int register_encoding); +void PhaseOutput::pd_perform_mach_node_analysis() { +} + +int MachNode::pd_alignment_required() const { + return 1; +} + +int MachNode::compute_padding(int current_offset) const { + return 0; +} + // Used by the DFA in dfa_sparc.cpp. // Check for being able to use a V9 branch-on-register. Requires a // compare-vs-zero, equal/not-equal, of a value which was zero- or sign- @@ -1944,10 +1962,15 @@ const bool Matcher::convi2l_type_required = true; +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { return clone_base_plus_offset_address(m, mstack, address_visited); }
--- a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -53,7 +53,7 @@ } int IntelJccErratum::jcc_erratum_taint_node(MachNode* node, PhaseRegAlloc* regalloc) { - node->add_flag(Node::Flag_intel_jcc_erratum); + node->add_flag(Node::PD::Flag_intel_jcc_erratum); return node->size(regalloc); } @@ -99,7 +99,7 @@ int jcc_size = mach->size(regalloc); if (index_in_block < block->number_of_nodes() - 1) { Node* next = block->get_node(index_in_block + 1); - if (next->is_Mach() && (next->as_Mach()->flags() & Node::Flag_intel_jcc_erratum)) { + if (next->is_Mach() && (next->as_Mach()->flags() & Node::PD::Flag_intel_jcc_erratum)) { jcc_size += mach->size(regalloc); } }
--- a/src/hotspot/cpu/x86/x86.ad Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/cpu/x86/x86.ad Fri Apr 10 17:10:22 2020 +0000 @@ -1165,11 +1165,51 @@ #endif }; +class Node::PD { +public: + enum NodeFlags { + Flag_intel_jcc_erratum = Node::_last_flag << 1, + _last_flag = Flag_intel_jcc_erratum + }; +}; + %} // end source_hpp source %{ #include "opto/addnode.hpp" +#include "c2_intelJccErratum_x86.hpp" + +void PhaseOutput::pd_perform_mach_node_analysis() { + if (VM_Version::has_intel_jcc_erratum()) { + int extra_padding = IntelJccErratum::tag_affected_machnodes(C, C->cfg(), C->regalloc()); + _buf_sizes._code += extra_padding; + } +} + +int MachNode::pd_alignment_required() const { + PhaseOutput* output = Compile::current()->output(); + Block* block = output->block(); + int index = output->index(); + if (VM_Version::has_intel_jcc_erratum() && IntelJccErratum::is_jcc_erratum_branch(block, this, index)) { + // Conservatively add worst case padding. We assume that relocInfo::addr_unit() is 1 on x86. + return IntelJccErratum::largest_jcc_size() + 1; + } else { + return 1; + } +} + +int MachNode::compute_padding(int current_offset) const { + if (flags() & Node::PD::Flag_intel_jcc_erratum) { + Compile* C = Compile::current(); + PhaseOutput* output = C->output(); + Block* block = output->block(); + int index = output->index(); + return IntelJccErratum::compute_padding(current_offset, this, block, index, C->regalloc()); + } else { + return 0; + } +} // Emit exception handler code. // Stuff framesize into a register and call a VM stub routine. @@ -1636,10 +1676,119 @@ return false; } +// This function identifies sub-graphs in which a 'load' node is +// input to two different nodes, and such that it can be matched +// with BMI instructions like blsi, blsr, etc. +// Example : for b = -a[i] & a[i] can be matched to blsi r32, m32. +// The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL* +// refers to the same node. +// +// Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop) +// This is a temporary solution until we make DAGs expressible in ADL. +template<typename ConType> +class FusedPatternMatcher { + Node* _op1_node; + Node* _mop_node; + int _con_op; + + static int match_next(Node* n, int next_op, int next_op_idx) { + if (n->in(1) == NULL || n->in(2) == NULL) { + return -1; + } + + if (next_op_idx == -1) { // n is commutative, try rotations + if (n->in(1)->Opcode() == next_op) { + return 1; + } else if (n->in(2)->Opcode() == next_op) { + return 2; + } + } else { + assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index"); + if (n->in(next_op_idx)->Opcode() == next_op) { + return next_op_idx; + } + } + return -1; + } + + public: + FusedPatternMatcher(Node* op1_node, Node* mop_node, int con_op) : + _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { } + + bool match(int op1, int op1_op2_idx, // op1 and the index of the op1->op2 edge, -1 if op1 is commutative + int op2, int op2_con_idx, // op2 and the index of the op2->con edge, -1 if op2 is commutative + typename ConType::NativeType con_value) { + if (_op1_node->Opcode() != op1) { + return false; + } + if (_mop_node->outcnt() > 2) { + return false; + } + op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx); + if (op1_op2_idx == -1) { + return false; + } + // Memory operation must be the other edge + int op1_mop_idx = (op1_op2_idx & 1) + 1; + + // Check that the mop node is really what we want + if (_op1_node->in(op1_mop_idx) == _mop_node) { + Node* op2_node = _op1_node->in(op1_op2_idx); + if (op2_node->outcnt() > 1) { + return false; + } + assert(op2_node->Opcode() == op2, "Should be"); + op2_con_idx = match_next(op2_node, _con_op, op2_con_idx); + if (op2_con_idx == -1) { + return false; + } + // Memory operation must be the other edge + int op2_mop_idx = (op2_con_idx & 1) + 1; + // Check that the memory operation is the same node + if (op2_node->in(op2_mop_idx) == _mop_node) { + // Now check the constant + const Type* con_type = op2_node->in(op2_con_idx)->bottom_type(); + if (con_type != Type::TOP && ConType::as_self(con_type)->get_con() == con_value) { + return true; + } + } + } + return false; + } +}; + +static bool is_bmi_pattern(Node* n, Node* m) { + assert(UseBMI1Instructions, "sanity"); + if (n != NULL && m != NULL) { + if (m->Opcode() == Op_LoadI) { + FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI); + return bmii.match(Op_AndI, -1, Op_SubI, 1, 0) || + bmii.match(Op_AndI, -1, Op_AddI, -1, -1) || + bmii.match(Op_XorI, -1, Op_AddI, -1, -1); + } else if (m->Opcode() == Op_LoadL) { + FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL); + return bmil.match(Op_AndL, -1, Op_SubL, 1, 0) || + bmil.match(Op_AndL, -1, Op_AddL, -1, -1) || + bmil.match(Op_XorL, -1, Op_AddL, -1, -1); + } + } + return false; +} + +// Should the matcher clone input 'm' of node 'n'? +bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + // If 'n' and 'm' are part of a graph for BMI instruction, clone the input 'm'. + if (UseBMI1Instructions && is_bmi_pattern(n, m)) { + mstack.push(m, Visit); + return true; + } + return false; +} + // Should the Matcher clone shifts on addressing modes, expecting them // to be subsumed into complex addressing expressions or compute them // into registers? -bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { +bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { Node *off = m->in(AddPNode::Offset); if (off->is_Con()) { address_visited.test_set(m->_idx); // Flag as address_visited
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -462,12 +462,6 @@ void os::Linux::set_fpu_control_word(int fpu_control) { } -// Check that the linux kernel version is 2.4 or higher since earlier -// versions do not support SSE without patches. -bool os::supports_sse() { - return true; -} - bool os::is_allocatable(size_t bytes) { return true; }
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,9 +27,6 @@ #define OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP static void setup_fpu(); - static bool supports_sse(); - - static jlong rdtsc(); static bool is_allocatable(size_t bytes);
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.inline.hpp Tue Apr 07 18:30:32 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP -#define OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP - -#include "runtime/os.hpp" - -// See http://www.technovelty.org/code/c/reading-rdtsc.htl for details -inline jlong os::rdtsc() { - uint64_t res; - uint32_t ts1, ts2; - __asm__ __volatile__ ("rdtsc" : "=a" (ts1), "=d" (ts2)); - res = ((uint64_t)ts1 | (uint64_t)ts2 << 32); - return (jlong)res; -} - -#endif // OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP
--- a/src/hotspot/share/classfile/classLoader.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/classfile/classLoader.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -220,9 +220,9 @@ return SymbolTable::new_symbol(name, start - base, end - base); } -// Given a fully qualified class name, find its defining package in the class loader's +// Given a fully qualified package name, find its defining package in the class loader's // package entry table. -PackageEntry* ClassLoader::get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data, TRAPS) { +PackageEntry* ClassLoader::get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data) { if (pkg_name == NULL) { return NULL; } @@ -396,9 +396,9 @@ if (!Universe::is_module_initialized()) { location = (*JImageFindResource)(_jimage, JAVA_BASE_NAME, get_jimage_version_string(), name, &size); } else { - PackageEntry* package_entry = ClassLoader::get_package_entry(pkg_name, loader_data, CHECK_NULL); + PackageEntry* package_entry = ClassLoader::get_package_entry(pkg_name, loader_data); if (package_entry != NULL) { - ResourceMark rm; + ResourceMark rm(THREAD); // Get the module name ModuleEntry* module = package_entry->module(); assert(module != NULL, "Boot classLoader package missing module"); @@ -1147,7 +1147,7 @@ // Find the class' defining module in the boot loader's module entry table TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name); TempNewSymbol pkg_name = package_from_class_name(class_name_symbol); - PackageEntry* pkg_entry = get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL); + PackageEntry* pkg_entry = get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()); ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL; // If the module system has not defined java.base yet, then
--- a/src/hotspot/share/classfile/classLoader.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/classfile/classLoader.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -272,9 +272,7 @@ static bool get_canonical_path(const char* orig, char* out, int len); static const char* file_name_for_class_name(const char* class_name, int class_name_len); - static PackageEntry* get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data, TRAPS); - - public: + static PackageEntry* get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data); static int crc32(int crc, const char* buf, int len); static bool update_class_path_entry_list(const char *path, bool check_for_duplicates,
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -703,8 +703,11 @@ // It's not guaranteed that the class is from the classpath if the // PackageEntry cannot be found from the AppClassloader. Need to check // the boot and platform classloader as well. - if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL && - get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) { + ClassLoaderData* platform_loader_data = + ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader()); // can be NULL during bootstrap + if ((platform_loader_data == NULL || + ClassLoader::get_package_entry(pkg_name, platform_loader_data) == NULL) && + ClassLoader::get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) { // The PackageEntry is not defined in any of the boot/platform/app classloaders. // The archived class must from -cp path and not from the runtime image. if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_class_paths_start_index() &&
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -248,14 +248,6 @@ PackageEntry* pkg_entry, ModuleEntry* mod_entry, TRAPS); - static PackageEntry* get_package_entry(Symbol* pkg, - ClassLoaderData *loader_data) { - if (loader_data != NULL) { - PackageEntryTable* pkgEntryTable = loader_data->packages(); - return pkgEntryTable->lookup_only(pkg); - } - return NULL; - } static bool add_unregistered_class(InstanceKlass* k, TRAPS); static InstanceKlass* dump_time_resolve_super_or_fail(Symbol* child_name,
--- a/src/hotspot/share/code/codeCache.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/code/codeCache.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -1073,8 +1073,8 @@ length = old_compiled_method_table->length(); for (int i = 0; i < length; i++) { CompiledMethod* cm = old_compiled_method_table->at(i); - // Only walk alive nmethods, the dead ones will get removed by the sweeper. - if (cm->is_alive()) { + // Only walk alive nmethods, the dead ones will get removed by the sweeper or GC. + if (cm->is_alive() && !cm->is_unloading()) { old_compiled_method_table->at(i)->metadata_do(f); } }
--- a/src/hotspot/share/code/compiledMethod.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/code/compiledMethod.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -642,6 +642,11 @@ continue; } is_in_static_stub = false; + if (is_unloading()) { + // If the nmethod itself is dying, then it may point at dead metadata. + // Nobody should follow that metadata; it is strictly unsafe. + continue; + } metadata_Relocation* r = iter.metadata_reloc(); Metadata* md = r->metadata_value(); if (md != NULL && md->is_method()) {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -209,14 +209,15 @@ } HeapWord* -G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first, +G1CollectedHeap::humongous_obj_allocate_initialize_regions(HeapRegion* first_hr, uint num_regions, size_t word_size) { - assert(first != G1_NO_HRM_INDEX, "pre-condition"); + assert(first_hr != NULL, "pre-condition"); assert(is_humongous(word_size), "word_size should be humongous"); assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); // Index of last region in the series. + uint first = first_hr->hrm_index(); uint last = first + num_regions - 1; // We need to initialize the region(s) we just discovered. This is @@ -231,10 +232,8 @@ size_t word_size_sum = (size_t) num_regions * HeapRegion::GrainWords; assert(word_size <= word_size_sum, "sanity"); - // This will be the "starts humongous" region. - HeapRegion* first_hr = region_at(first); - // The header of the new object will be placed at the bottom of - // the first region. + // The passed in hr will be the "starts humongous" region. The header + // of the new object will be placed at the bottom of this region. HeapWord* new_obj = first_hr->bottom(); // This will be the new top of the new object. HeapWord* obj_top = new_obj + word_size; @@ -340,57 +339,28 @@ _verifier->verify_region_sets_optional(); - uint first = G1_NO_HRM_INDEX; uint obj_regions = (uint) humongous_obj_size_in_regions(word_size); - if (obj_regions == 1) { - // Only one region to allocate, try to use a fast path by directly allocating - // from the free lists. Do not try to expand here, we will potentially do that - // later. - HeapRegion* hr = new_region(word_size, HeapRegionType::Humongous, false /* do_expand */); - if (hr != NULL) { - first = hr->hrm_index(); - } - } else { - // Policy: Try only empty regions (i.e. already committed first). Maybe we - // are lucky enough to find some. - first = _hrm->find_contiguous_only_empty(obj_regions); - if (first != G1_NO_HRM_INDEX) { - _hrm->allocate_free_regions_starting_at(first, obj_regions); - } - } - - if (first == G1_NO_HRM_INDEX) { + // Policy: First try to allocate a humongous object in the free list. + HeapRegion* humongous_start = _hrm->allocate_humongous(obj_regions); + if (humongous_start == NULL) { // Policy: We could not find enough regions for the humongous object in the // free list. Look through the heap to find a mix of free and uncommitted regions. - // If so, try expansion. - first = _hrm->find_contiguous_empty_or_unavailable(obj_regions); - if (first != G1_NO_HRM_INDEX) { - // We found something. Make sure these regions are committed, i.e. expand - // the heap. Alternatively we could do a defragmentation GC. - log_debug(gc, ergo, heap)("Attempt heap expansion (humongous allocation request failed). Allocation request: " SIZE_FORMAT "B", - word_size * HeapWordSize); - - _hrm->expand_at(first, obj_regions, workers()); + // If so, expand the heap and allocate the humongous object. + humongous_start = _hrm->expand_and_allocate_humongous(obj_regions); + if (humongous_start != NULL) { + // We managed to find a region by expanding the heap. + log_debug(gc, ergo, heap)("Heap expansion (humongous allocation request). Allocation request: " SIZE_FORMAT "B", + word_size * HeapWordSize); policy()->record_new_heap_size(num_regions()); - -#ifdef ASSERT - for (uint i = first; i < first + obj_regions; ++i) { - HeapRegion* hr = region_at(i); - assert(hr->is_free(), "sanity"); - assert(hr->is_empty(), "sanity"); - assert(is_on_master_free_list(hr), "sanity"); - } -#endif - _hrm->allocate_free_regions_starting_at(first, obj_regions); } else { // Policy: Potentially trigger a defragmentation GC. } } HeapWord* result = NULL; - if (first != G1_NO_HRM_INDEX) { - result = humongous_obj_allocate_initialize_regions(first, obj_regions, word_size); + if (humongous_start != NULL) { + result = humongous_obj_allocate_initialize_regions(humongous_start, obj_regions, word_size); assert(result != NULL, "it should always return a valid result"); // A successful humongous object allocation changes the used space @@ -4892,8 +4862,7 @@ log_debug(gc, ergo, heap)("Attempt heap expansion (requested address range outside heap bounds). region size: " SIZE_FORMAT "B", HeapRegion::GrainWords * HeapWordSize); } - _hrm->allocate_free_regions_starting_at(index, 1); - return region_at(index); + return _hrm->allocate_free_regions_starting_at(index, 1); } return NULL; }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -409,7 +409,7 @@ // Initialize a contiguous set of free regions of length num_regions // and starting at index first so that they appear as a single // humongous region. - HeapWord* humongous_obj_allocate_initialize_regions(uint first, + HeapWord* humongous_obj_allocate_initialize_regions(HeapRegion* first_hr, uint num_regions, size_t word_size);
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -135,6 +135,35 @@ return hr; } +HeapRegion* HeapRegionManager::allocate_humongous_from_free_list(uint num_regions) { + uint candidate = find_contiguous_in_free_list(num_regions); + if (candidate == G1_NO_HRM_INDEX) { + return NULL; + } + return allocate_free_regions_starting_at(candidate, num_regions); +} + +HeapRegion* HeapRegionManager::allocate_humongous_allow_expand(uint num_regions) { + uint candidate = find_contiguous_allow_expand(num_regions); + if (candidate == G1_NO_HRM_INDEX) { + return NULL; + } + expand_exact(candidate, num_regions, G1CollectedHeap::heap()->workers()); + return allocate_free_regions_starting_at(candidate, num_regions); +} + +HeapRegion* HeapRegionManager::allocate_humongous(uint num_regions) { + // Special case a single region to avoid expensive search. + if (num_regions == 1) { + return allocate_free_region(HeapRegionType::Humongous, G1NUMA::AnyNodeIndex); + } + return allocate_humongous_from_free_list(num_regions); +} + +HeapRegion* HeapRegionManager::expand_and_allocate_humongous(uint num_regions) { + return allocate_humongous_allow_expand(num_regions); +} + #ifdef ASSERT bool HeapRegionManager::is_free(HeapRegion* hr) const { return _free_list.contains(hr); @@ -271,6 +300,19 @@ return expanded; } +void HeapRegionManager::expand_exact(uint start, uint num_regions, WorkGang* pretouch_workers) { + assert(num_regions != 0, "Need to request at least one region"); + uint end = start + num_regions; + + for (uint i = start; i < end; i++) { + if (!is_available(i)) { + make_regions_available(i, 1, pretouch_workers); + } + } + + verify_optional(); +} + uint HeapRegionManager::expand_on_preferred_node(uint preferred_index) { uint expand_candidate = UINT_MAX; for (uint i = 0; i < max_length(); i++) { @@ -291,7 +333,7 @@ return 0; } - make_regions_available(expand_candidate, 1, NULL); + expand_exact(expand_candidate, 1, NULL); return 1; } @@ -300,36 +342,61 @@ return region_node_index == preferred_node_index; } -uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) { - uint found = 0; - size_t length_found = 0; - uint cur = 0; +void HeapRegionManager::guarantee_contiguous_range(uint start, uint num_regions) { + // General sanity check, regions found should either be available and empty + // or not available so that we can make them available and use them. + for (uint i = start; i < (start + num_regions); i++) { + HeapRegion* hr = _regions.get_by_index(i); + guarantee(!is_available(i) || hr->is_free(), + "Found region sequence starting at " UINT32_FORMAT ", length " UINT32_FORMAT + " that is not free at " UINT32_FORMAT ". Hr is " PTR_FORMAT ", type is %s", + start, num_regions, i, p2i(hr), hr->get_type_str()); + } +} - while (length_found < num && cur < max_length()) { - HeapRegion* hr = _regions.get_by_index(cur); - if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) { - // This region is a potential candidate for allocation into. - length_found++; - } else { - // This region is not a candidate. The next region is the next possible one. - found = cur + 1; - length_found = 0; +uint HeapRegionManager::find_contiguous_in_range(uint start, uint end, uint num_regions) { + assert(start <= end, "precondition"); + assert(num_regions >= 1, "precondition"); + uint candidate = start; // First region in candidate sequence. + uint unchecked = candidate; // First unchecked region in candidate. + // While the candidate sequence fits in the range... + while (num_regions <= (end - candidate)) { + // Walk backward over the regions for the current candidate. + for (uint i = candidate + num_regions - 1; true; --i) { + if (is_available(i) && !at(i)->is_free()) { + // Region i can't be used, so restart with i+1 as the start + // of a new candidate sequence, and with the region after the + // old candidate sequence being the first unchecked region. + unchecked = candidate + num_regions; + candidate = i + 1; + break; + } else if (i == unchecked) { + // All regions of candidate sequence have passed check. + guarantee_contiguous_range(candidate, num_regions); + return candidate; + } } - cur++; } + return G1_NO_HRM_INDEX; +} + +uint HeapRegionManager::find_contiguous_in_free_list(uint num_regions) { + BitMap::idx_t range_start = 0; + BitMap::idx_t range_end = range_start; + uint candidate = G1_NO_HRM_INDEX; - if (length_found == num) { - for (uint i = found; i < (found + num); i++) { - HeapRegion* hr = _regions.get_by_index(i); - // sanity check - guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()), - "Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT - " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr)); - } - return found; - } else { - return G1_NO_HRM_INDEX; - } + do { + range_start = _available_map.get_next_one_offset(range_end); + range_end = _available_map.get_next_zero_offset(range_start); + candidate = find_contiguous_in_range((uint) range_start, (uint) range_end, num_regions); + } while (candidate == G1_NO_HRM_INDEX && range_end < max_length()); + + return candidate; +} + +uint HeapRegionManager::find_contiguous_allow_expand(uint num_regions) { + // Find any candidate. + return find_contiguous_in_range(0, max_length(), num_regions); } HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -94,11 +94,19 @@ // Notify other data structures about change in the heap layout. void update_committed_space(HeapWord* old_end, HeapWord* new_end); - // Find a contiguous set of empty or uncommitted regions of length num and return + // Find a contiguous set of empty or uncommitted regions of length num_regions and return // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful. - // If only_empty is true, only empty regions are considered. - // Searches from bottom to top of the heap, doing a first-fit. - uint find_contiguous(size_t num, bool only_empty); + // Start and end defines the range to seek in, policy is first-fit. + uint find_contiguous_in_range(uint start, uint end, uint num_regions); + // Find a contiguous set of empty regions of length num_regions. Returns the start index + // of that set, or G1_NO_HRM_INDEX. + uint find_contiguous_in_free_list(uint num_regions); + // Find a contiguous set of empty or unavailable regions of length num_regions. Returns the + // start index of that set, or G1_NO_HRM_INDEX. + uint find_contiguous_allow_expand(uint num_regions); + + void guarantee_contiguous_range(uint start, uint num_regions) ; + // Finds the next sequence of unavailable regions starting from start_idx. Returns the // length of the sequence found. If this result is zero, no such sequence could be found, // otherwise res_idx indicates the start index of these regions. @@ -122,6 +130,14 @@ void uncommit_regions(uint index, size_t num_regions = 1); // Allocate a new HeapRegion for the given index. HeapRegion* new_heap_region(uint hrm_index); + + // Humongous allocation helpers + virtual HeapRegion* allocate_humongous_from_free_list(uint num_regions); + virtual HeapRegion* allocate_humongous_allow_expand(uint num_regions); + + // Expand helper for cases when the regions to expand are well defined. + void expand_exact(uint start, uint num_regions, WorkGang* pretouch_workers); + #ifdef ASSERT public: bool is_free(HeapRegion* hr) const; @@ -183,7 +199,13 @@ // Allocate a free region with specific node index. If fails allocate with next node index. virtual HeapRegion* allocate_free_region(HeapRegionType type, uint requested_node_index); - inline void allocate_free_regions_starting_at(uint first, uint num_regions); + // Allocate a humongous object from the free list + HeapRegion* allocate_humongous(uint num_regions); + + // Allocate a humongous object by expanding the heap + HeapRegion* expand_and_allocate_humongous(uint num_regions); + + inline HeapRegion* allocate_free_regions_starting_at(uint first, uint num_regions); // Remove all regions from the free list. void remove_all_free_regions() { @@ -233,13 +255,6 @@ // Try to expand on the given node index. virtual uint expand_on_preferred_node(uint node_index); - // Find a contiguous set of empty regions of length num. Returns the start index of - // that set, or G1_NO_HRM_INDEX. - virtual uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); } - // Find a contiguous set of empty or unavailable regions of length num. Returns the - // start index of that set, or G1_NO_HRM_INDEX. - virtual uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); } - HeapRegion* next_region_in_heap(const HeapRegion* r) const; // Find the highest free or uncommitted region in the reserved heap,
--- a/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -73,8 +73,10 @@ _free_list.add_ordered(hr); } -inline void HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) { - _free_list.remove_starting_at(at(first), num_regions); +inline HeapRegion* HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) { + HeapRegion* start = at(first); + _free_list.remove_starting_at(start, num_regions); + return start; } #endif // SHARE_GC_G1_HEAPREGIONMANAGER_INLINE_HPP
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -69,7 +69,7 @@ _g1h(G1CollectedHeap::heap()), _m(m), _num_occupied(0), - _coarse_map(G1CollectedHeap::heap()->max_regions(), mtGC), + _coarse_map(mtGC), _n_coarse_entries(0), _fine_grain_regions(NULL), _n_fine_entries(0), @@ -132,7 +132,7 @@ RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index(); // If the region is already coarsened, return. - if (_coarse_map.at(from_hrm_ind)) { + if (is_region_coarsened(from_hrm_ind)) { assert(contains_reference(from), "We just found " PTR_FORMAT " in the Coarse table", p2i(from)); return; } @@ -226,7 +226,6 @@ PerRegionTable* max = NULL; jint max_occ = 0; PerRegionTable** max_prev = NULL; - size_t max_ind; size_t i = _fine_eviction_start; for (size_t k = 0; k < _fine_eviction_sample_size; k++) { @@ -244,7 +243,6 @@ if (max == NULL || cur_occ > max_occ) { max = cur; max_prev = prev; - max_ind = i; max_occ = cur_occ; } prev = cur->collision_list_next_addr(); @@ -265,7 +263,15 @@ // Set the corresponding coarse bit. size_t max_hrm_index = (size_t) max->hr()->hrm_index(); - if (!_coarse_map.at(max_hrm_index)) { + if (_n_coarse_entries == 0) { + // This will lazily initialize an uninitialized bitmap + _coarse_map.reinitialize(G1CollectedHeap::heap()->max_regions()); + _coarse_map.at_put(max_hrm_index, true); + // Release store guarantees that the bitmap has initialized before any + // concurrent reader will ever see a non-zero value for _n_coarse_entries + // (when read with load_acquire) + Atomic::release_store(&_n_coarse_entries, _n_coarse_entries + 1); + } else if (!_coarse_map.at(max_hrm_index)) { _coarse_map.at_put(max_hrm_index, true); _n_coarse_entries++; } @@ -344,19 +350,25 @@ HeapRegion* hr = _g1h->heap_region_containing(from); RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index(); // Is this region in the coarse map? - if (_coarse_map.at(hr_ind)) return true; + if (is_region_coarsened(hr_ind)) return true; PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, hr); if (prt != NULL) { return prt->contains_reference(from); - } else { CardIdx_t card_index = card_within_region(from, hr); return _sparse_table.contains_card(hr_ind, card_index); } } +// A load_acquire on _n_coarse_entries - coupled with the release_store in +// delete_region_table - guarantees we don't access _coarse_map before +// it's been properly initialized. +bool OtherRegionsTable::is_region_coarsened(RegionIdx_t from_hrm_ind) const { + return Atomic::load_acquire(&_n_coarse_entries) > 0 && _coarse_map.at(from_hrm_ind); +} + HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetTable* bot, HeapRegion* hr) : _bot(bot),
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -153,6 +153,9 @@ // Clear the entire contents of this remembered set. void clear(); + + // Safe for use by concurrent readers outside _m + bool is_region_coarsened(RegionIdx_t from_hrm_ind) const; }; class PerRegionTable: public CHeapObj<mtGC> {
--- a/src/hotspot/share/gc/g1/heapRegionSet.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionSet.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -229,7 +229,7 @@ // Remove all (contiguous) regions from first to first + num_regions -1 from // this list. - // Num_regions must be > 1. + // Num_regions must be >= 1. void remove_starting_at(HeapRegion* first, uint num_regions); virtual void verify();
--- a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -325,18 +325,28 @@ return hr; } -uint HeterogeneousHeapRegionManager::find_contiguous_only_empty(size_t num) { +HeapRegion* HeterogeneousHeapRegionManager::allocate_humongous_from_free_list(uint num_regions) { if (has_borrowed_regions()) { - return G1_NO_HRM_INDEX; + return NULL; } - return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, true); + uint candidate = find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num_regions, true); + if (candidate == G1_NO_HRM_INDEX) { + return NULL; + } + return allocate_free_regions_starting_at(candidate, num_regions); } -uint HeterogeneousHeapRegionManager::find_contiguous_empty_or_unavailable(size_t num) { +HeapRegion* HeterogeneousHeapRegionManager::allocate_humongous_allow_expand(uint num_regions) { if (has_borrowed_regions()) { - return G1_NO_HRM_INDEX; + return NULL; } - return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, false); + uint candidate = find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num_regions, false); + if (candidate == G1_NO_HRM_INDEX) { + return NULL; + } + + expand_exact(candidate, num_regions, NULL); + return allocate_free_regions_starting_at(candidate, num_regions); } uint HeterogeneousHeapRegionManager::find_contiguous(size_t start, size_t end, size_t num, bool empty_only) {
--- a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -120,6 +120,8 @@ void prepare_for_full_collection_end(); virtual HeapRegion* allocate_free_region(HeapRegionType type, uint node_index); + virtual HeapRegion* allocate_humongous_from_free_list(uint num_regions); + virtual HeapRegion* allocate_humongous_allow_expand(uint num_regions); // Return maximum number of regions that heap can expand to. uint max_expandable_length() const; @@ -130,12 +132,6 @@ // Override. uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers); - // Override. This function is called for humongous allocation, so we need to find empty regions in nv-dimm. - uint find_contiguous_only_empty(size_t num); - - // Override. This function is called for humongous allocation, so we need to find empty or unavailable regions in nv-dimm. - uint find_contiguous_empty_or_unavailable(size_t num); - // Overrides base class implementation to find highest free region in dram. uint find_highest_free(bool* expanded);
--- a/src/hotspot/share/gc/g1/sparsePRT.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/sparsePRT.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -85,6 +85,21 @@ float RSHashTable::TableOccupancyFactor = 0.5f; +// The empty table can't hold any entries and is effectively immutable +// This means it can be used as an initial sentinel value +static int empty_buckets[] = { RSHashTable::NullEntry }; +RSHashTable RSHashTable::empty_table; + +RSHashTable::RSHashTable() : + _num_entries(0), + _capacity(0), + _capacity_mask(0), + _occupied_entries(0), + _entries(NULL), + _buckets(empty_buckets), + _free_region(0), + _free_list(NullEntry) { } + RSHashTable::RSHashTable(size_t capacity) : _num_entries((capacity * TableOccupancyFactor) + 1), _capacity(capacity), @@ -99,14 +114,19 @@ } RSHashTable::~RSHashTable() { - FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries); - FREE_C_HEAP_ARRAY(int, _buckets); + // Nothing to free for empty RSHashTable + if (_buckets != empty_buckets) { + assert(_entries != NULL, "invariant"); + FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries); + FREE_C_HEAP_ARRAY(int, _buckets); + } } void RSHashTable::clear() { + assert(_buckets != empty_buckets, "Shouldn't call this for the empty_table"); _occupied_entries = 0; - guarantee(_entries != NULL, "INV"); - guarantee(_buckets != NULL, "INV"); + guarantee(_entries != NULL, "invariant"); + guarantee(_buckets != NULL, "invariant"); guarantee(_capacity <= ((size_t)1 << (sizeof(int)*BitsPerByte-1)) - 1, "_capacity too large"); @@ -119,6 +139,7 @@ } SparsePRT::AddCardResult RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) { + assert(this != &empty_table, "can't add a card to the empty table"); SparsePRTEntry* e = entry_for_region_ind_create(region_ind); assert(e != NULL && e->r_ind() == region_ind, "Postcondition of call above."); @@ -207,7 +228,7 @@ bool RSHashTableBucketIter::has_next(SparsePRTEntry*& entry) { while (_bl_ind == RSHashTable::NullEntry) { - if (_tbl_ind == (int)_rsht->capacity() - 1) { + if (_tbl_ind + 1 >= _rsht->capacity()) { return false; } _tbl_ind++; @@ -231,12 +252,14 @@ // ---------------------------------------------------------------------- SparsePRT::SparsePRT() : - _table(new RSHashTable(InitialCapacity)) { + _table(&RSHashTable::empty_table) { } SparsePRT::~SparsePRT() { - delete _table; + if (_table != &RSHashTable::empty_table) { + delete _table; + } } @@ -262,23 +285,27 @@ } void SparsePRT::clear() { - // If the entry table is not at initial capacity, just create a new one. - if (_table->capacity() != InitialCapacity) { + // If the entry table not at initial capacity, just reset to the empty table. + if (_table->capacity() == InitialCapacity) { + _table->clear(); + } else if (_table != &RSHashTable::empty_table) { delete _table; - _table = new RSHashTable(InitialCapacity); - } else { - _table->clear(); + _table = &RSHashTable::empty_table; } } void SparsePRT::expand() { RSHashTable* last = _table; - _table = new RSHashTable(last->capacity() * 2); - for (size_t i = 0; i < last->num_entries(); i++) { - SparsePRTEntry* e = last->entry((int)i); - if (e->valid_entry()) { - _table->add_entry(e); + if (last != &RSHashTable::empty_table) { + _table = new RSHashTable(last->capacity() * 2); + for (size_t i = 0; i < last->num_entries(); i++) { + SparsePRTEntry* e = last->entry((int)i); + if (e->valid_entry()) { + _table->add_entry(e); + } } + delete last; + } else { + _table = new RSHashTable(InitialCapacity); } - delete last; }
--- a/src/hotspot/share/gc/g1/sparsePRT.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/g1/sparsePRT.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -173,11 +173,15 @@ // deleted from any bucket lists. void free_entry(int fi); + // For the empty sentinel created at static initialization time + RSHashTable(); + public: RSHashTable(size_t capacity); ~RSHashTable(); static const int NullEntry = -1; + static RSHashTable empty_table; bool should_expand() const { return _occupied_entries == _num_entries; } @@ -215,8 +219,8 @@ // This is embedded in HRRS iterator. class RSHashTableBucketIter { - int _tbl_ind; // [-1, 0.._rsht->_capacity) - int _bl_ind; // [-1, 0.._rsht->_capacity) + uint _tbl_ind; // [0.._rsht->_capacity) + int _bl_ind; // [-1, 0.._rsht->_capacity) RSHashTable* _rsht;
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -125,35 +125,6 @@ } } -oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, oop* load_addr) { - return load_reference_barrier_mutator_work(obj, load_addr); -} - -oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, narrowOop* load_addr) { - return load_reference_barrier_mutator_work(obj, load_addr); -} - -template <class T> -oop ShenandoahBarrierSet::load_reference_barrier_mutator_work(oop obj, T* load_addr) { - assert(ShenandoahLoadRefBarrier, "should be enabled"); - shenandoah_assert_in_cset(load_addr, obj); - - oop fwd = resolve_forwarded_not_null_mutator(obj); - if (obj == fwd) { - assert(_heap->is_evacuation_in_progress(), - "evac should be in progress"); - ShenandoahEvacOOMScope scope; - fwd = _heap->evacuate_object(obj, Thread::current()); - } - - if (load_addr != NULL && fwd != obj) { - // Since we are here and we know the load address, update the reference. - ShenandoahHeap::cas_oop(fwd, load_addr, obj); - } - - return fwd; -} - oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { assert(ShenandoahLoadRefBarrier, "should be enabled"); if (!CompressedOops::is_null(obj)) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -96,11 +96,8 @@ oop load_reference_barrier(oop obj); oop load_reference_barrier_not_null(oop obj); - oop load_reference_barrier_mutator(oop obj, oop* load_addr); - oop load_reference_barrier_mutator(oop obj, narrowOop* load_addr); - template <class T> - oop load_reference_barrier_mutator_work(oop obj, T* load_addr); + inline oop load_reference_barrier_mutator(oop obj, T* load_addr); oop load_reference_barrier_native(oop obj, oop* load_addr); oop load_reference_barrier_native(oop obj, narrowOop* load_addr);
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -53,6 +53,27 @@ return ShenandoahForwarding::get_forwardee_mutator(p); } +template <class T> +inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, T* load_addr) { + assert(ShenandoahLoadRefBarrier, "should be enabled"); + shenandoah_assert_in_cset(load_addr, obj); + + oop fwd = resolve_forwarded_not_null_mutator(obj); + if (obj == fwd) { + assert(_heap->is_evacuation_in_progress(), + "evac should be in progress"); + ShenandoahEvacOOMScope scope; + fwd = _heap->evacuate_object(obj, Thread::current()); + } + + if (load_addr != NULL && fwd != obj) { + // Since we are here and we know the load address, update the reference. + ShenandoahHeap::cas_oop(fwd, load_addr, obj); + } + + return fwd; +} + inline void ShenandoahBarrierSet::enqueue(oop obj) { assert(_satb_mark_queue_set.is_active(), "only get here when SATB active");
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -30,6 +30,7 @@ #include "gc/shared/weakProcessor.inline.hpp" #include "gc/shared/gcTimer.hpp" +#include "gc/shared/gcTrace.hpp" #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/strongRootsScope.hpp" @@ -687,16 +688,18 @@ if (_heap->has_forwarded_objects()) { ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id)); - rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, - &complete_gc, &executor, - &pt); - + const ReferenceProcessorStats& stats = + rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, + &complete_gc, &executor, + &pt); + _heap->tracer()->report_gc_reference_stats(stats); } else { ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id)); - rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, - &complete_gc, &executor, - &pt); - + const ReferenceProcessorStats& stats = + rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, + &complete_gc, &executor, + &pt); + _heap->tracer()->report_gc_reference_stats(stats); } pt.print_all_references(); @@ -817,7 +820,7 @@ bool strdedup) { ShenandoahObjToScanQueue* q = get_queue(w); - jushort* ld = _heap->get_liveness_cache(w); + ShenandoahLiveData* ld = _heap->get_liveness_cache(w); // TODO: We can clean up this if we figure out how to do templated oop closures that // play nice with specialized_oop_iterators. @@ -863,7 +866,7 @@ } template <class T, bool CANCELLABLE> -void ShenandoahConcurrentMark::mark_loop_work(T* cl, jushort* live_data, uint worker_id, TaskTerminator *terminator) { +void ShenandoahConcurrentMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *terminator) { uintx stride = ShenandoahMarkLoopStride; ShenandoahHeap* heap = ShenandoahHeap::heap();
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -46,7 +46,7 @@ // private: template <class T> - inline void do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task); + inline void do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, ShenandoahMarkTask* task); template <class T> inline void do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop array); @@ -54,10 +54,10 @@ template <class T> inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow); - inline void count_liveness(jushort* live_data, oop obj); + inline void count_liveness(ShenandoahLiveData* live_data, oop obj); template <class T, bool CANCELLABLE> - void mark_loop_work(T* cl, jushort* live_data, uint worker_id, TaskTerminator *t); + void mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *t); template <bool CANCELLABLE> void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ReferenceProcessor *rp, bool strdedup);
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -37,7 +37,7 @@ #include "runtime/prefetch.inline.hpp" template <class T> -void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) { +void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, ShenandoahMarkTask* task) { oop obj = task->obj(); shenandoah_assert_not_forwarded(NULL, obj); @@ -67,28 +67,22 @@ } } -inline void ShenandoahConcurrentMark::count_liveness(jushort* live_data, oop obj) { +inline void ShenandoahConcurrentMark::count_liveness(ShenandoahLiveData* 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(); if (!region->is_humongous_start()) { assert(!region->is_humongous(), "Cannot have continuations here"); - size_t max = (1 << (sizeof(jushort) * 8)) - 1; - if (size >= max) { - // too big, add to region data directly - region->increase_live_data_gc_words(size); + ShenandoahLiveData cur = live_data[region_idx]; + size_t new_val = size + cur; + if (new_val >= SHENANDOAH_LIVEDATA_MAX) { + // overflow, flush to region data + region->increase_live_data_gc_words(new_val); + live_data[region_idx] = 0; } else { - jushort cur = live_data[region_idx]; - size_t new_val = cur + size; - if (new_val >= max) { - // overflow, flush to region data - region->increase_live_data_gc_words(new_val); - live_data[region_idx] = 0; - } else { - // still good, remember in locals - live_data[region_idx] = (jushort) new_val; - } + // still good, remember in locals + live_data[region_idx] = (ShenandoahLiveData) new_val; } } else { shenandoah_assert_in_correct_region(NULL, obj);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -357,10 +357,10 @@ // Initialize the rest of GC subsystems // - _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC); + _liveness_cache = NEW_C_HEAP_ARRAY(ShenandoahLiveData*, _max_workers, mtGC); for (uint worker = 0; worker < _max_workers; worker++) { - _liveness_cache[worker] = NEW_C_HEAP_ARRAY(jushort, _num_regions, mtGC); - Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort)); + _liveness_cache[worker] = NEW_C_HEAP_ARRAY(ShenandoahLiveData, _num_regions, mtGC); + Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(ShenandoahLiveData)); } // There should probably be Shenandoah-specific options for these, @@ -1408,12 +1408,12 @@ set_concurrent_mark_in_progress(true); // We need to reset all TLABs because we'd lose marks on all objects allocated in them. { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::make_parsable); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::make_parsable); make_parsable(true); } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_region_states); ShenandoahInitMarkUpdateRegionStateClosure cl; parallel_heap_region_iterate(&cl); } @@ -1424,7 +1424,7 @@ concurrent_mark()->mark_roots(ShenandoahPhaseTimings::scan_roots); if (UseTLAB) { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::resize_tlabs); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::resize_tlabs); resize_tlabs(); } @@ -1513,7 +1513,7 @@ } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_region_states); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_region_states); ShenandoahFinalMarkUpdateRegionStateClosure cl; parallel_heap_region_iterate(&cl); @@ -1522,19 +1522,19 @@ // Force the threads to reacquire their TLABs outside the collection set. { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::retire_tlabs); make_parsable(true); } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::choose_cset); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::choose_cset); ShenandoahHeapLocker locker(lock()); _collection_set->clear(); heuristics()->choose_collection_set(_collection_set); } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset); ShenandoahHeapLocker locker(lock()); _free_set->rebuild(); } @@ -1547,7 +1547,7 @@ // If collection set has candidates, start evacuation. // Otherwise, bypass the rest of the cycle. if (!collection_set()->is_empty()) { - ShenandoahGCPhase init_evac(ShenandoahPhaseTimings::init_evac); + ShenandoahGCSubPhase init_evac(ShenandoahPhaseTimings::init_evac); if (ShenandoahVerify) { verifier()->verify_before_evacuation(); @@ -1808,7 +1808,7 @@ full_gc()->do_it(cause); if (UseTLAB) { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); resize_all_tlabs(); } @@ -2104,16 +2104,16 @@ // Unload classes and purge SystemDictionary. { - ShenandoahGCPhase phase(full_gc ? - ShenandoahPhaseTimings::full_gc_purge_class_unload : - ShenandoahPhaseTimings::purge_class_unload); + ShenandoahGCSubPhase phase(full_gc ? + ShenandoahPhaseTimings::full_gc_purge_class_unload : + ShenandoahPhaseTimings::purge_class_unload); purged_class = SystemDictionary::do_unloading(gc_timer()); } { - ShenandoahGCPhase phase(full_gc ? - ShenandoahPhaseTimings::full_gc_purge_par : - ShenandoahPhaseTimings::purge_par); + ShenandoahGCSubPhase phase(full_gc ? + ShenandoahPhaseTimings::full_gc_purge_par : + ShenandoahPhaseTimings::purge_par); ShenandoahIsAliveSelector is_alive; uint num_workers = _workers->active_workers(); ShenandoahClassUnloadingTask unlink_task(is_alive.is_alive_closure(), num_workers, purged_class); @@ -2121,9 +2121,9 @@ } { - ShenandoahGCPhase phase(full_gc ? - ShenandoahPhaseTimings::full_gc_purge_cldg : - ShenandoahPhaseTimings::purge_cldg); + ShenandoahGCSubPhase phase(full_gc ? + ShenandoahPhaseTimings::full_gc_purge_cldg : + ShenandoahPhaseTimings::purge_cldg); ClassLoaderDataGraph::purge(); } // Resize and verify metaspace @@ -2136,14 +2136,14 @@ // However, we do need to "null" dead oops in the roots, if can not be done // in concurrent cycles. void ShenandoahHeap::stw_process_weak_roots(bool full_gc) { - ShenandoahGCPhase root_phase(full_gc ? - ShenandoahPhaseTimings::full_gc_purge : - ShenandoahPhaseTimings::purge); + ShenandoahGCSubPhase root_phase(full_gc ? + ShenandoahPhaseTimings::full_gc_purge : + ShenandoahPhaseTimings::purge); uint num_workers = _workers->active_workers(); ShenandoahPhaseTimings::Phase timing_phase = full_gc ? ShenandoahPhaseTimings::full_gc_purge_par : ShenandoahPhaseTimings::purge_par; - ShenandoahGCPhase phase(timing_phase); + ShenandoahGCSubPhase phase(timing_phase); ShenandoahGCWorkerPhase worker_phase(timing_phase); // Cleanup weak roots @@ -2286,7 +2286,7 @@ } #endif -GCTimer* ShenandoahHeap::gc_timer() const { +ConcurrentGCTimer* ShenandoahHeap::gc_timer() const { return _gc_timer; } @@ -2398,7 +2398,7 @@ set_evacuation_in_progress(false); { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs); retire_and_reset_gclabs(); } @@ -2412,7 +2412,7 @@ set_update_refs_in_progress(true); { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_prepare); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_refs_prepare); make_parsable(true); @@ -2461,7 +2461,7 @@ // Check if there is left-over work, and finish it if (_update_refs_iterator.has_next()) { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work); // Finish updating references where we left off. clear_cancelled_gc(); @@ -2491,7 +2491,7 @@ } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states); ShenandoahFinalUpdateRefsUpdateRegionStateClosure cl; parallel_heap_region_iterate(&cl); @@ -2499,7 +2499,7 @@ } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset); trash_cset_regions(); } @@ -2515,7 +2515,7 @@ } { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset); ShenandoahHeapLocker locker(lock()); _free_set->rebuild(); } @@ -2661,11 +2661,12 @@ } void ShenandoahHeap::entry_init_mark() { + const char* msg = init_mark_event_message(); + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark); - const char* msg = init_mark_event_message(); - GCTraceTime(Info, gc) time(msg, gc_timer()); - EventMark em("%s", msg); ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_init_marking(), @@ -2675,11 +2676,12 @@ } void ShenandoahHeap::entry_final_mark() { + const char* msg = final_mark_event_message(); + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark); - const char* msg = final_mark_event_message(); - GCTraceTime(Info, gc) time(msg, gc_timer()); - EventMark em("%s", msg); ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_final_marking(), @@ -2689,26 +2691,26 @@ } void ShenandoahHeap::entry_init_updaterefs() { + static const char* msg = "Pause Init Update Refs"; + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs); - static const char* msg = "Pause Init Update Refs"; - GCTraceTime(Info, gc) time(msg, gc_timer()); - EventMark em("%s", msg); - // No workers used in this phase, no setup required op_init_updaterefs(); } void ShenandoahHeap::entry_final_updaterefs() { + static const char* msg = "Pause Final Update Refs"; + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs); - static const char* msg = "Pause Final Update Refs"; - GCTraceTime(Info, gc) time(msg, gc_timer()); - EventMark em("%s", msg); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_final_update_ref(), "final reference update"); @@ -2717,13 +2719,13 @@ } void ShenandoahHeap::entry_full(GCCause::Cause cause) { + static const char* msg = "Pause Full"; + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc); - static const char* msg = "Pause Full"; - GCTraceTime(Info, gc) time(msg, gc_timer(), cause, true); - EventMark em("%s", msg); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_fullgc(), "full gc"); @@ -2732,14 +2734,14 @@ } void ShenandoahHeap::entry_degenerated(int point) { + ShenandoahDegenPoint dpoint = (ShenandoahDegenPoint)point; + const char* msg = degen_event_message(dpoint); + ShenandoahPausePhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc); - ShenandoahDegenPoint dpoint = (ShenandoahDegenPoint)point; - const char* msg = degen_event_message(dpoint); - GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); - EventMark em("%s", msg); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_stw_degenerated(), "stw degenerated gc"); @@ -2753,9 +2755,11 @@ TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters()); const char* msg = conc_mark_event_message(); - GCTraceTime(Info, gc) time(msg); + ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); + ShenandoahGCPhase conc_mark_phase(ShenandoahPhaseTimings::conc_mark); + ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_marking(), "concurrent marking"); @@ -2765,13 +2769,14 @@ } void ShenandoahHeap::entry_evac() { - ShenandoahGCPhase conc_evac_phase(ShenandoahPhaseTimings::conc_evac); TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters()); static const char* msg = "Concurrent evacuation"; - GCTraceTime(Info, gc) time(msg); + ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); + ShenandoahGCPhase conc_evac_phase(ShenandoahPhaseTimings::conc_evac); + ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_evac(), "concurrent evacuation"); @@ -2781,12 +2786,12 @@ } void ShenandoahHeap::entry_updaterefs() { + static const char* msg = "Concurrent update references"; + ShenandoahConcurrentPhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_update_refs); - static const char* msg = "Concurrent update references"; - GCTraceTime(Info, gc) time(msg); - EventMark em("%s", msg); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref(), "concurrent reference update"); @@ -2796,12 +2801,12 @@ } void ShenandoahHeap::entry_roots() { + static const char* msg = "Concurrent roots processing"; + ShenandoahConcurrentPhase gc_phase(msg); + EventMark em("%s", msg); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots); - static const char* msg = "Concurrent roots processing"; - GCTraceTime(Info, gc) time(msg); - EventMark em("%s", msg); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), "concurrent root processing"); @@ -2811,12 +2816,12 @@ } void ShenandoahHeap::entry_cleanup() { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); - static const char* msg = "Concurrent cleanup"; - GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); + ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */); EventMark em("%s", msg); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup); + // This phase does not use workers, no need for setup try_inject_alloc_failure(); @@ -2824,12 +2829,12 @@ } void ShenandoahHeap::entry_reset() { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_reset); - static const char* msg = "Concurrent reset"; - GCTraceTime(Info, gc) time(msg); + ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_reset); + ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_reset(), "concurrent reset"); @@ -2841,10 +2846,10 @@ void ShenandoahHeap::entry_preclean() { if (ShenandoahPreclean && process_references()) { static const char* msg = "Concurrent precleaning"; - GCTraceTime(Info, gc) time(msg); + ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase conc_preclean(ShenandoahPhaseTimings::conc_preclean); + ShenandoahGCSubPhase conc_preclean(ShenandoahPhaseTimings::conc_preclean); ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_preclean(), @@ -2858,10 +2863,10 @@ void ShenandoahHeap::entry_uncommit(double shrink_before) { static const char *msg = "Concurrent uncommit"; - GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); + ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_uncommit); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_uncommit); op_uncommit(shrink_before); } @@ -3008,7 +3013,7 @@ } } -jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) { +ShenandoahLiveData* ShenandoahHeap::get_liveness_cache(uint worker_id) { #ifdef ASSERT assert(_liveness_cache != NULL, "sanity"); assert(worker_id < _max_workers, "sanity"); @@ -3022,11 +3027,11 @@ void ShenandoahHeap::flush_liveness_cache(uint worker_id) { assert(worker_id < _max_workers, "sanity"); assert(_liveness_cache != NULL, "sanity"); - jushort* ld = _liveness_cache[worker_id]; + ShenandoahLiveData* ld = _liveness_cache[worker_id]; for (uint i = 0; i < num_regions(); i++) { - ShenandoahHeapRegion* r = get_region(i); - jushort live = ld[i]; + ShenandoahLiveData live = ld[i]; if (live > 0) { + ShenandoahHeapRegion* r = get_region(i); r->increase_live_data_gc_words(live); ld[i] = 0; }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -62,6 +62,16 @@ class ShenandoahWorkGang; class VMStructs; +// Used for buffering per-region liveness data. +// Needed since ShenandoahHeapRegion uses atomics to update liveness. +// The ShenandoahHeap array has max-workers elements, each of which is an array of +// uint16_t * max_regions. The choice of uint16_t is not accidental: +// there is a tradeoff between static/dynamic footprint that translates +// into cache pressure (which is already high during marking), and +// too many atomic updates. uint32_t is too large, uint8_t is too small. +typedef uint16_t ShenandoahLiveData; +#define SHENANDOAH_LIVEDATA_MAX ((ShenandoahLiveData)-1) + class ShenandoahRegionIterator : public StackObj { private: ShenandoahHeap* _heap; @@ -469,7 +479,7 @@ GrowableArray<MemoryPool*> memory_pools(); MemoryUsage memory_usage(); GCTracer* tracer(); - GCTimer* gc_timer() const; + ConcurrentGCTimer* gc_timer() const; // ---------- Reference processing // @@ -613,15 +623,7 @@ bool _bitmap_region_special; bool _aux_bitmap_region_special; - // Used for buffering per-region liveness data. - // Needed since ShenandoahHeapRegion uses atomics to update liveness. - // - // The array has max-workers elements, each of which is an array of - // jushort * max_regions. The choice of jushort is not accidental: - // there is a tradeoff between static/dynamic footprint that translates - // into cache pressure (which is already high during marking), and - // too many atomic updates. size_t/jint is too large, jbyte is too small. - jushort** _liveness_cache; + ShenandoahLiveData** _liveness_cache; public: inline ShenandoahMarkingContext* complete_marking_context() const; @@ -651,7 +653,7 @@ bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false); // Liveness caching support - jushort* get_liveness_cache(uint worker_id); + ShenandoahLiveData* get_liveness_cache(uint worker_id); void flush_liveness_cache(uint worker_id); // ---------- Evacuation support
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -174,14 +174,6 @@ cset_percent); } -void ShenandoahHeuristics::record_gc_start() { - // Do nothing -} - -void ShenandoahHeuristics::record_gc_end() { - // Do nothing -} - void ShenandoahHeuristics::record_cycle_start() { _cycle_start = os::elapsedTime(); }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -96,10 +96,6 @@ ShenandoahHeuristics(); virtual ~ShenandoahHeuristics(); - void record_gc_start(); - - void record_gc_end(); - void record_metaspace_oom() { _metaspace_oom.set(); } void clear_metaspace_oom() { _metaspace_oom.unset(); } bool has_metaspace_oom() const { return _metaspace_oom.is_set(); }
--- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -43,10 +43,7 @@ // 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; - } + assert(orig != NULL, "should be optimized out"); shenandoah_assert_correct(NULL, orig); // store the original value that was in the field reference assert(ShenandoahThreadLocalData::satb_mark_queue(thread).is_active(), "Shouldn't be here otherwise");
--- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -140,7 +140,7 @@ ShenandoahHeap* const heap = ShenandoahHeap::heap(); { MutexLocker cldg_ml(ClassLoaderDataGraph_lock); - unloading_occurred = SystemDictionary::do_unloading(NULL /* gc_timer */); + unloading_occurred = SystemDictionary::do_unloading(heap->gc_timer()); } Klass::clean_weak_klass_links(unloading_occurred);
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -26,7 +26,6 @@ #include "jfr/jfrEvents.hpp" #include "gc/shared/gcCause.hpp" -#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTrace.hpp" #include "gc/shared/gcWhen.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -47,7 +46,7 @@ _heap->set_gc_cause(cause); _timer->register_gc_start(); _tracer->report_gc_start(cause, _timer->gc_start()); - _heap->trace_heap(GCWhen::BeforeGC, _tracer); + _heap->trace_heap_before_gc(_tracer); _heap->shenandoah_policy()->record_cycle_start(); _heap->heuristics()->record_cycle_start(); @@ -66,7 +65,7 @@ ShenandoahGCSession::~ShenandoahGCSession() { _heap->heuristics()->record_cycle_end(); _timer->register_gc_end(); - _heap->trace_heap(GCWhen::AfterGC, _tracer); + _heap->trace_heap_after_gc(_tracer); _tracer->report_gc_end(_timer->gc_end(), _timer->time_partitions()); assert(!ShenandoahGCPhase::is_current_phase_valid(), "No current GC phase"); _heap->set_gc_cause(GCCause::_no_gc); @@ -74,10 +73,6 @@ ShenandoahGCPauseMark::ShenandoahGCPauseMark(uint gc_id, SvcGCMarker::reason_type type) : _heap(ShenandoahHeap::heap()), _gc_id_mark(gc_id), _svc_gc_mark(type), _is_gc_active_mark() { - - // FIXME: It seems that JMC throws away level 0 events, which are the Shenandoah - // pause events. Create this pseudo level 0 event to push real events to level 1. - _heap->gc_timer()->register_gc_pause_start("Shenandoah", Ticks::now()); _trace_pause.initialize(_heap->stw_memory_manager(), _heap->gc_cause(), /* allMemoryPoolsAffected */ true, /* recordGCBeginTime = */ true, @@ -88,16 +83,29 @@ /* recordGCEndTime = */ true, /* countCollection = */ true ); +} - _heap->heuristics()->record_gc_start(); +ShenandoahPausePhase::ShenandoahPausePhase(const char* title) : + _tracer(title), + _timer(ShenandoahHeap::heap()->gc_timer()) { + _timer->register_gc_pause_start(title); +} + +ShenandoahPausePhase::~ShenandoahPausePhase() { + _timer->register_gc_pause_end(); } -ShenandoahGCPauseMark::~ShenandoahGCPauseMark() { - _heap->gc_timer()->register_gc_pause_end(Ticks::now()); - _heap->heuristics()->record_gc_end(); +ShenandoahConcurrentPhase::ShenandoahConcurrentPhase(const char* title, bool log_heap_usage) : + _tracer(title, NULL, GCCause::_no_gc, log_heap_usage), + _timer(ShenandoahHeap::heap()->gc_timer()) { + _timer->register_gc_concurrent_start(title); } -ShenandoahGCPhase::ShenandoahGCPhase(const ShenandoahPhaseTimings::Phase phase) : +ShenandoahConcurrentPhase::~ShenandoahConcurrentPhase() { + _timer->register_gc_concurrent_end(); +} + +ShenandoahGCPhase::ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase) : _timings(ShenandoahHeap::heap()->phase_timings()), _phase(phase) { assert(!Thread::current()->is_Worker_thread() && (Thread::current()->is_VM_thread() || @@ -131,6 +139,16 @@ } } +ShenandoahGCSubPhase::ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase) : + ShenandoahGCPhase(phase), + _timer(ShenandoahHeap::heap()->gc_timer()) { + _timer->register_gc_phase_start(ShenandoahPhaseTimings::phase_name(phase), Ticks::now()); +} + +ShenandoahGCSubPhase::~ShenandoahGCSubPhase() { + _timer->register_gc_phase_end(Ticks::now()); +} + ShenandoahGCWorkerPhase::ShenandoahGCWorkerPhase(const ShenandoahPhaseTimings::Phase phase) : _timings(ShenandoahHeap::heap()->phase_timings()), _phase(phase) { _timings->record_workers_start(_phase);
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -26,6 +26,7 @@ #define SHARE_GC_SHENANDOAH_SHENANDOAHUTILS_HPP #include "gc/shared/gcCause.hpp" +#include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/gcVMOperations.hpp" #include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/suspendibleThreadSet.hpp" @@ -40,7 +41,6 @@ #include "services/memoryService.hpp" class GCTimer; -class GCTracer; class ShenandoahGCSession : public StackObj { private: @@ -54,6 +54,26 @@ ~ShenandoahGCSession(); }; +class ShenandoahPausePhase : public StackObj { +private: + GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer; + ConcurrentGCTimer* const _timer; + +public: + ShenandoahPausePhase(const char* title); + ~ShenandoahPausePhase(); +}; + +class ShenandoahConcurrentPhase : public StackObj { +private: + GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer; + ConcurrentGCTimer* const _timer; + +public: + ShenandoahConcurrentPhase(const char* title, bool log_heap_usage = false); + ~ShenandoahConcurrentPhase(); +}; + class ShenandoahGCPhase : public StackObj { private: static ShenandoahPhaseTimings::Phase _current_phase; @@ -73,6 +93,15 @@ static bool is_root_work_phase(); }; +class ShenandoahGCSubPhase: public ShenandoahGCPhase { +private: + ConcurrentGCTimer* const _timer; + +public: + ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase); + ~ShenandoahGCSubPhase(); +}; + class ShenandoahGCWorkerPhase : public StackObj { private: ShenandoahPhaseTimings* const _timings; @@ -93,7 +122,6 @@ public: ShenandoahGCPauseMark(uint gc_id, SvcGCMarker::reason_type type); - ~ShenandoahGCPauseMark(); }; class ShenandoahSafepoint : public AllStatic {
--- a/src/hotspot/share/opto/loopUnswitch.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/loopUnswitch.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -221,11 +221,11 @@ // Hardwire the control paths in the loops into if(true) and if(false) _igvn.rehash_node_delayed(unswitch_iff); - short_circuit_if(unswitch_iff, proj_true); + dominated_by(proj_true, unswitch_iff, false, false); IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If(); _igvn.rehash_node_delayed(unswitch_iff_clone); - short_circuit_if(unswitch_iff_clone, proj_false); + dominated_by(proj_false, unswitch_iff_clone, false, false); // Reoptimize loops loop->record_for_igvn();
--- a/src/hotspot/share/opto/machnode.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/machnode.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -286,11 +286,12 @@ // Return the alignment required (in units of relocInfo::addr_unit()) // for this instruction (must be a power of 2) - virtual int alignment_required() const { return 1; } + int pd_alignment_required() const; + virtual int alignment_required() const { return pd_alignment_required(); } // Return the padding (in bytes) to be emitted before this // instruction to properly align it. - virtual int compute_padding(int current_offset) const { return 0; } + virtual int compute_padding(int current_offset) const; // Return number of relocatable values contained in this instruction virtual int reloc() const { return 0; }
--- a/src/hotspot/share/opto/matcher.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/matcher.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -1918,105 +1918,6 @@ return OptoReg::as_OptoReg(regs.first()); } -// This function identifies sub-graphs in which a 'load' node is -// input to two different nodes, and such that it can be matched -// with BMI instructions like blsi, blsr, etc. -// Example : for b = -a[i] & a[i] can be matched to blsi r32, m32. -// The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL* -// refers to the same node. -#ifdef X86 -// Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop) -// This is a temporary solution until we make DAGs expressible in ADL. -template<typename ConType> -class FusedPatternMatcher { - Node* _op1_node; - Node* _mop_node; - int _con_op; - - static int match_next(Node* n, int next_op, int next_op_idx) { - if (n->in(1) == NULL || n->in(2) == NULL) { - return -1; - } - - if (next_op_idx == -1) { // n is commutative, try rotations - if (n->in(1)->Opcode() == next_op) { - return 1; - } else if (n->in(2)->Opcode() == next_op) { - return 2; - } - } else { - assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index"); - if (n->in(next_op_idx)->Opcode() == next_op) { - return next_op_idx; - } - } - return -1; - } -public: - FusedPatternMatcher(Node* op1_node, Node *mop_node, int con_op) : - _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { } - - bool match(int op1, int op1_op2_idx, // op1 and the index of the op1->op2 edge, -1 if op1 is commutative - int op2, int op2_con_idx, // op2 and the index of the op2->con edge, -1 if op2 is commutative - typename ConType::NativeType con_value) { - if (_op1_node->Opcode() != op1) { - return false; - } - if (_mop_node->outcnt() > 2) { - return false; - } - op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx); - if (op1_op2_idx == -1) { - return false; - } - // Memory operation must be the other edge - int op1_mop_idx = (op1_op2_idx & 1) + 1; - - // Check that the mop node is really what we want - if (_op1_node->in(op1_mop_idx) == _mop_node) { - Node *op2_node = _op1_node->in(op1_op2_idx); - if (op2_node->outcnt() > 1) { - return false; - } - assert(op2_node->Opcode() == op2, "Should be"); - op2_con_idx = match_next(op2_node, _con_op, op2_con_idx); - if (op2_con_idx == -1) { - return false; - } - // Memory operation must be the other edge - int op2_mop_idx = (op2_con_idx & 1) + 1; - // Check that the memory operation is the same node - if (op2_node->in(op2_mop_idx) == _mop_node) { - // Now check the constant - const Type* con_type = op2_node->in(op2_con_idx)->bottom_type(); - if (con_type != Type::TOP && ConType::as_self(con_type)->get_con() == con_value) { - return true; - } - } - } - return false; - } -}; - - -bool Matcher::is_bmi_pattern(Node *n, Node *m) { - if (n != NULL && m != NULL) { - if (m->Opcode() == Op_LoadI) { - FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI); - return bmii.match(Op_AndI, -1, Op_SubI, 1, 0) || - bmii.match(Op_AndI, -1, Op_AddI, -1, -1) || - bmii.match(Op_XorI, -1, Op_AddI, -1, -1); - } else if (m->Opcode() == Op_LoadL) { - FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL); - return bmil.match(Op_AndL, -1, Op_SubL, 1, 0) || - bmil.match(Op_AndL, -1, Op_AddL, -1, -1) || - bmil.match(Op_XorL, -1, Op_AddL, -1, -1); - } - } - return false; -} -#endif // X86 - bool Matcher::is_vshift_con_pattern(Node *n, Node *m) { if (n != NULL && m != NULL) { return VectorNode::is_vector_shift(n) && @@ -2026,6 +1927,20 @@ } +bool Matcher::clone_node(Node* n, Node* m, Matcher::MStack& mstack) { + // Must clone all producers of flags, or we will not match correctly. + // Suppose a compare setting int-flags is shared (e.g., a switch-tree) + // then it will match into an ideal Op_RegFlags. Alas, the fp-flags + // are also there, so we may match a float-branch to int-flags and + // expect the allocator to haul the flags from the int-side to the + // fp-side. No can do. + if (_must_clone[m->Opcode()]) { + mstack.push(m, Visit); + return true; + } + return pd_clone_node(n, m, mstack); +} + bool Matcher::clone_base_plus_offset_address(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { Node *off = m->in(AddPNode::Offset); if (off->is_Con()) { @@ -2045,7 +1960,7 @@ //------------------------------find_shared------------------------------------ // Set bits if Node is shared or otherwise a root -void Matcher::find_shared( Node *n ) { +void Matcher::find_shared(Node* n) { // Allocate stack of size C->live_nodes() * 2 to avoid frequent realloc MStack mstack(C->live_nodes() * 2); // Mark nodes as address_visited if they are inputs to an address expression @@ -2083,36 +1998,17 @@ if (find_shared_visit(mstack, n, nop, mem_op, mem_addr_idx)) { continue; } - for(int i = n->req() - 1; i >= 0; --i) { // For my children - Node *m = n->in(i); // Get ith input - if (m == NULL) continue; // Ignore NULLs - uint mop = m->Opcode(); - - // Must clone all producers of flags, or we will not match correctly. - // Suppose a compare setting int-flags is shared (e.g., a switch-tree) - // then it will match into an ideal Op_RegFlags. Alas, the fp-flags - // are also there, so we may match a float-branch to int-flags and - // expect the allocator to haul the flags from the int-side to the - // fp-side. No can do. - if( _must_clone[mop] ) { - mstack.push(m, Visit); - continue; // for(int i = ...) + for (int i = n->req() - 1; i >= 0; --i) { // For my children + Node* m = n->in(i); // Get ith input + if (m == NULL) { + continue; // Ignore NULLs } - - // if 'n' and 'm' are part of a graph for BMI instruction, clone this node. -#ifdef X86 - if (UseBMI1Instructions && is_bmi_pattern(n, m)) { - mstack.push(m, Visit); - continue; - } -#endif - if (is_vshift_con_pattern(n, m)) { - mstack.push(m, Visit); + if (clone_node(n, m, mstack)) { continue; } // Clone addressing expressions as they are "free" in memory access instructions - if (mem_op && i == mem_addr_idx && mop == Op_AddP && + if (mem_op && i == mem_addr_idx && m->is_AddP() && // When there are other uses besides address expressions // put it on stack and mark as shared. !is_visited(m)) { @@ -2122,7 +2018,7 @@ // But they should be marked as shared if there are other uses // besides address expressions. - if (clone_address_expressions(m->as_AddP(), mstack, address_visited)) { + if (pd_clone_address_expressions(m->as_AddP(), mstack, address_visited)) { continue; } } // if( mem_op &&
--- a/src/hotspot/share/opto/matcher.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/matcher.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -121,10 +121,6 @@ bool find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx); void find_shared_post_visit(Node* n, uint opcode); -#ifdef X86 - bool is_bmi_pattern(Node *n, Node *m); -#endif - bool is_vshift_con_pattern(Node *n, Node *m); // Debug and profile information for nodes in old space: @@ -452,10 +448,15 @@ // Some hardware have expensive CMOV for float and double. static const int float_cmove_cost(); + // Should the input 'm' of node 'n' be cloned during matching? + // Reports back whether the node was cloned or not. + bool clone_node(Node* n, Node* m, Matcher::MStack& mstack); + bool pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack); + // Should the Matcher clone shifts on addressing modes, expecting them to // be subsumed into complex addressing expressions or compute them into // registers? True for Intel but false for most RISCs - bool clone_address_expressions(AddPNode* m, MStack& mstack, VectorSet& address_visited); + bool pd_clone_address_expressions(AddPNode* m, MStack& mstack, VectorSet& address_visited); // Clone base + offset address expression bool clone_base_plus_offset_address(AddPNode* m, MStack& mstack, VectorSet& address_visited);
--- a/src/hotspot/share/opto/node.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/node.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -28,6 +28,7 @@ #include "libadt/vectset.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "opto/ad.hpp" #include "opto/castnode.hpp" #include "opto/cfgnode.hpp" #include "opto/connode.hpp" @@ -1033,7 +1034,12 @@ //------------------------------init_NodeProperty------------------------------ void Node::init_NodeProperty() { assert(_max_classes <= max_jushort, "too many NodeProperty classes"); - assert(_max_flags <= max_jushort, "too many NodeProperty flags"); + assert(max_flags() <= max_jushort, "too many NodeProperty flags"); +} + +//-----------------------------max_flags--------------------------------------- +juint Node::max_flags() { + return (PD::_last_flag << 1) - 1; // allow flags combination } #endif
--- a/src/hotspot/share/opto/node.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/node.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -740,25 +740,28 @@ Flag_is_scheduled = Flag_is_reduction << 1, Flag_has_vector_mask_set = Flag_is_scheduled << 1, Flag_is_expensive = Flag_has_vector_mask_set << 1, - Flag_intel_jcc_erratum = Flag_is_expensive << 1, - _max_flags = (Flag_intel_jcc_erratum << 1) - 1 // allow flags combination + _last_flag = Flag_is_expensive }; + class PD; + private: jushort _class_id; jushort _flags; + static juint max_flags(); + protected: // These methods should be called from constructors only. void init_class_id(jushort c) { _class_id = c; // cast out const } void init_flags(uint fl) { - assert(fl <= _max_flags, "invalid node flag"); + assert(fl <= max_flags(), "invalid node flag"); _flags |= fl; } void clear_flag(uint fl) { - assert(fl <= _max_flags, "invalid node flag"); + assert(fl <= max_flags(), "invalid node flag"); _flags &= ~fl; }
--- a/src/hotspot/share/opto/output.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/output.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -53,9 +53,6 @@ #include "utilities/macros.hpp" #include "utilities/powerOfTwo.hpp" #include "utilities/xmlstream.hpp" -#ifdef X86 -#include "c2_intelJccErratum_x86.hpp" -#endif #ifndef PRODUCT #define DEBUG_ARG(x) , x @@ -243,7 +240,10 @@ _node_bundling_limit(0), _node_bundling_base(NULL), _orig_pc_slot(0), - _orig_pc_slot_offset_in_bytes(0) { + _orig_pc_slot_offset_in_bytes(0), + _buf_sizes(), + _block(NULL), + _index(0) { C->set_output(this); if (C->stub_name() == NULL) { _orig_pc_slot = C->fixed_slots() - (sizeof(address) / VMRegImpl::stack_slot_size); @@ -257,6 +257,15 @@ } } +void PhaseOutput::perform_mach_node_analysis() { + // Late barrier analysis must be done after schedule and bundle + // Otherwise liveness based spilling will fail + BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); + bs->late_barrier_analysis(); + + pd_perform_mach_node_analysis(); +} + // Convert Nodes to instruction bits and pass off to the VM void PhaseOutput::Output() { // RootNode goes @@ -320,10 +329,10 @@ } // Keeper of sizing aspects - BufferSizingData buf_sizes = BufferSizingData(); + _buf_sizes = BufferSizingData(); // Initialize code buffer - estimate_buffer_size(buf_sizes._const); + estimate_buffer_size(_buf_sizes._const); if (C->failing()) return; // Pre-compute the length of blocks and replace @@ -331,27 +340,17 @@ // Must be done before ScheduleAndBundle due to SPARC delay slots uint* blk_starts = NEW_RESOURCE_ARRAY(uint, C->cfg()->number_of_blocks() + 1); blk_starts[0] = 0; - shorten_branches(blk_starts, buf_sizes); + shorten_branches(blk_starts); ScheduleAndBundle(); if (C->failing()) { return; } - // Late barrier analysis must be done after schedule and bundle - // Otherwise liveness based spilling will fail - BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); - bs->late_barrier_analysis(); - -#ifdef X86 - if (VM_Version::has_intel_jcc_erratum()) { - int extra_padding = IntelJccErratum::tag_affected_machnodes(C, C->cfg(), C->regalloc()); - buf_sizes._code += extra_padding; - } -#endif + perform_mach_node_analysis(); // Complete sizing of codebuffer - CodeBuffer* cb = init_buffer(buf_sizes); + CodeBuffer* cb = init_buffer(); if (cb == NULL || C->failing()) { return; } @@ -433,7 +432,7 @@ // The architecture description provides short branch variants for some long // branch instructions. Replace eligible long branches with short branches. -void PhaseOutput::shorten_branches(uint* blk_starts, BufferSizingData& buf_sizes) { +void PhaseOutput::shorten_branches(uint* blk_starts) { // Compute size of each block, method size, and relocation information size uint nblocks = C->cfg()->number_of_blocks(); @@ -468,6 +467,7 @@ uint nop_size = (new MachNopNode())->size(C->regalloc()); for (uint i = 0; i < nblocks; i++) { // For all blocks Block* block = C->cfg()->get_block(i); + _block = block; // During short branch replacement, we store the relative (to blk_starts) // offset of jump in jmp_offset, rather than the absolute offset of jump. @@ -483,18 +483,12 @@ uint last_inst = block->number_of_nodes(); uint blk_size = 0; for (uint j = 0; j < last_inst; j++) { - Node* nj = block->get_node(j); + _index = j; + Node* nj = block->get_node(_index); // Handle machine instruction nodes if (nj->is_Mach()) { - MachNode *mach = nj->as_Mach(); + MachNode* mach = nj->as_Mach(); blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding -#ifdef X86 - if (VM_Version::has_intel_jcc_erratum() && IntelJccErratum::is_jcc_erratum_branch(block, mach, j)) { - // Conservatively add worst case padding - blk_size += IntelJccErratum::largest_jcc_size(); - } -#endif - reloc_size += mach->reloc(); if (mach->is_MachCall()) { // add size information for trampoline stub @@ -697,9 +691,9 @@ // The CodeBuffer will expand the locs array if this estimate is too low. reloc_size *= 10 / sizeof(relocInfo); - buf_sizes._reloc = reloc_size; - buf_sizes._code = code_size; - buf_sizes._stub = stub_size; + _buf_sizes._reloc = reloc_size; + _buf_sizes._code = code_size; + _buf_sizes._stub = stub_size; } //------------------------------FillLocArray----------------------------------- @@ -1239,11 +1233,10 @@ init_scratch_buffer_blob(const_req); } -CodeBuffer* PhaseOutput::init_buffer(BufferSizingData& buf_sizes) { - - int stub_req = buf_sizes._stub; - int code_req = buf_sizes._code; - int const_req = buf_sizes._const; +CodeBuffer* PhaseOutput::init_buffer() { + int stub_req = _buf_sizes._stub; + int code_req = _buf_sizes._code; + int const_req = _buf_sizes._const; int pad_req = NativeCall::instruction_size; @@ -1272,7 +1265,7 @@ total_req += deopt_handler_req; // deopt MH handler CodeBuffer* cb = code_buffer(); - cb->initialize(total_req, buf_sizes._reloc); + cb->initialize(total_req, _buf_sizes._reloc); // Have we run out of code space? if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) { @@ -1361,6 +1354,7 @@ for (uint i = 0; i < nblocks; i++) { Block* block = C->cfg()->get_block(i); + _block = block; Node* head = block->head(); // If this block needs to start aligned (i.e, can be reached other @@ -1391,6 +1385,7 @@ // Emit block normally, except for last instruction. // Emit means "dump code bits into code buffer". for (uint j = 0; j<last_inst; j++) { + _index = j; // Get the node Node* n = block->get_node(j); @@ -1437,12 +1432,6 @@ // Avoid back to back some instructions. padding = nop_size; } -#ifdef X86 - if (mach->flags() & Node::Flag_intel_jcc_erratum) { - assert(padding == 0, "can't have contradicting padding requirements"); - padding = IntelJccErratum::compute_padding(current_offset, mach, block, j, C->regalloc()); - } -#endif if (padding > 0) { assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
--- a/src/hotspot/share/opto/output.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/opto/output.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -96,6 +96,13 @@ ConstantTable _constant_table; // The constant table for this compilation unit. + BufferSizingData _buf_sizes; + Block* _block; + uint _index; + + void perform_mach_node_analysis(); + void pd_perform_mach_node_analysis(); + public: PhaseOutput(); ~PhaseOutput(); @@ -119,9 +126,13 @@ // Constant table ConstantTable& constant_table() { return _constant_table; } + // Code emission iterator + Block* block() { return _block; } + int index() { return _index; } + // The architecture description provides short branch variants for some long // branch instructions. Replace eligible long branches with short branches. - void shorten_branches(uint* blk_starts, BufferSizingData& buf_sizes); + void shorten_branches(uint* blk_starts); ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id); void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, ObjectValue* sv); void FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, @@ -132,7 +143,7 @@ // Initialize code buffer void estimate_buffer_size(int& const_req); - CodeBuffer* init_buffer(BufferSizingData& buf_sizes); + CodeBuffer* init_buffer(); // Write out basic block data to code buffer void fill_buffer(CodeBuffer* cb, uint* blk_starts);
--- a/src/hotspot/share/runtime/biasedLocking.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/biasedLocking.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -622,7 +622,7 @@ p2i(biaser), p2i(obj())); RevokeOneBias revoke(obj, requester, biaser); - bool executed = Handshake::execute(&revoke, biaser); + bool executed = Handshake::execute_direct(&revoke, biaser); if (revoke.status_code() == NOT_REVOKED) { return NOT_REVOKED; } @@ -666,24 +666,24 @@ // Caller should have instantiated a ResourceMark object before calling this method void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) { + Thread* cur = Thread::current(); assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints"); - assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread"); + assert(cur == biased_locker || cur == biased_locker->active_handshaker(), "wrong thread"); markWord mark = obj->mark(); assert(mark.biased_locker() == biased_locker && obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant"); - log_trace(biasedlocking)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark " + log_trace(biasedlocking)("JavaThread(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark " INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT ", biaser " INTPTR_FORMAT " %s", - Thread::current()->is_VM_thread() ? "VMThread" : "JavaThread", - p2i(Thread::current()), + p2i(cur), p2i(obj), mark.value(), obj->klass()->external_name(), obj->klass()->prototype_header().value(), p2i(biased_locker), - Thread::current()->is_VM_thread() ? "" : "(walking own stack)"); + cur != biased_locker ? "" : "(walking own stack)"); markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
--- a/src/hotspot/share/runtime/handshake.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/handshake.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -37,50 +37,42 @@ #include "utilities/formatBuffer.hpp" #include "utilities/preserveException.hpp" -class HandshakeOperation: public StackObj { -public: - virtual void do_handshake(JavaThread* thread) = 0; -}; -class HandshakeThreadsOperation: public HandshakeOperation { - static Semaphore _done; +class HandshakeOperation: public StackObj { HandshakeClosure* _handshake_cl; + int32_t _pending_threads; bool _executed; + bool _is_direct; public: - HandshakeThreadsOperation(HandshakeClosure* cl) : _handshake_cl(cl), _executed(false) {} + HandshakeOperation(HandshakeClosure* cl, bool is_direct = false) : + _handshake_cl(cl), + _pending_threads(1), + _executed(false), + _is_direct(is_direct) {} + void do_handshake(JavaThread* thread); - bool thread_has_completed() { return _done.trywait(); } + bool is_completed() { + int32_t val = Atomic::load(&_pending_threads); + assert(val >= 0, "_pending_threads=%d cannot be negative", val); + return val == 0; + } + void add_target_count(int count) { Atomic::add(&_pending_threads, count, memory_order_relaxed); } bool executed() const { return _executed; } const char* name() { return _handshake_cl->name(); } -#ifdef ASSERT - void check_state() { - assert(!_done.trywait(), "Must be zero"); - } -#endif + bool is_direct() { return _is_direct; } }; -Semaphore HandshakeThreadsOperation::_done(0); - class VM_Handshake: public VM_Operation { const jlong _handshake_timeout; public: bool evaluate_at_safepoint() const { return false; } protected: - HandshakeThreadsOperation* const _op; - - VM_Handshake(HandshakeThreadsOperation* op) : - _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {} + HandshakeOperation* const _op; - void set_handshake(JavaThread* target) { - target->set_handshake_operation(_op); - } - - // This method returns true for threads completed their operation - // and true for threads canceled their operation. - // A cancellation can happen if the thread is exiting. - bool poll_for_completed_thread() { return _op->thread_has_completed(); } + VM_Handshake(HandshakeOperation* op) : + _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {} bool handshake_has_timed_out(jlong start_time); static void handle_timeout(); @@ -121,12 +113,10 @@ class VM_HandshakeOneThread: public VM_Handshake { JavaThread* _target; public: - VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) : + VM_HandshakeOneThread(HandshakeOperation* op, JavaThread* target) : VM_Handshake(op), _target(target) {} void doit() { - DEBUG_ONLY(_op->check_state();) - jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { start_time_ns = os::javaTimeNanos(); @@ -134,7 +124,7 @@ ThreadsListHandle tlh; if (tlh.includes(_target)) { - set_handshake(_target); + _target->set_handshake_operation(_op); } else { log_handshake_info(start_time_ns, _op->name(), 0, 0, "(thread dead)"); return; @@ -147,9 +137,15 @@ if (handshake_has_timed_out(timeout_start_time)) { handle_timeout(); } - by_vm_thread = _target->handshake_try_process_by_vmThread(); - } while (!poll_for_completed_thread()); - DEBUG_ONLY(_op->check_state();) + by_vm_thread = _target->handshake_try_process(_op); + } while (!_op->is_completed()); + + // This pairs up with the release store in do_handshake(). It prevents future + // loads from floating above the load of _pending_threads in is_completed() + // and thus prevents reading stale data modified in the handshake closure + // by the Handshakee. + OrderAccess::acquire(); + log_handshake_info(start_time_ns, _op->name(), 1, by_vm_thread ? 1 : 0); } @@ -160,11 +156,9 @@ class VM_HandshakeAllThreads: public VM_Handshake { public: - VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} + VM_HandshakeAllThreads(HandshakeOperation* op) : VM_Handshake(op) {} void doit() { - DEBUG_ONLY(_op->check_state();) - jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { start_time_ns = os::javaTimeNanos(); @@ -174,7 +168,7 @@ JavaThreadIteratorWithHandle jtiwh; int number_of_threads_issued = 0; for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { - set_handshake(thr); + thr->set_handshake_operation(_op); number_of_threads_issued++; } @@ -182,10 +176,11 @@ log_handshake_info(start_time_ns, _op->name(), 0, 0); return; } + // _op was created with a count == 1 so don't double count. + _op->add_target_count(number_of_threads_issued - 1); log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThread"); const jlong start_time = os::elapsed_counter(); - int number_of_threads_completed = 0; do { // Check if handshake operation has timed out if (handshake_has_timed_out(start_time)) { @@ -198,19 +193,18 @@ jtiwh.rewind(); for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { // A new thread on the ThreadsList will not have an operation, - // hence it is skipped in handshake_process_by_vmthread. - if (thr->handshake_try_process_by_vmThread()) { + // hence it is skipped in handshake_try_process. + if (thr->handshake_try_process(_op)) { handshake_executed_by_vm_thread++; } } - while (poll_for_completed_thread()) { - // Includes canceled operations by exiting threads. - number_of_threads_completed++; - } + } while (!_op->is_completed()); - } while (number_of_threads_issued > number_of_threads_completed); - assert(number_of_threads_issued == number_of_threads_completed, "Must be the same"); - DEBUG_ONLY(_op->check_state();) + // This pairs up with the release store in do_handshake(). It prevents future + // loads from floating above the load of _pending_threads in is_completed() + // and thus prevents reading stale data modified in the handshake closure + // by the Handshakee. + OrderAccess::acquire(); log_handshake_info(start_time_ns, _op->name(), number_of_threads_issued, handshake_executed_by_vm_thread); } @@ -218,7 +212,7 @@ VMOp_Type type() const { return VMOp_HandshakeAllThreads; } }; -void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { +void HandshakeOperation::do_handshake(JavaThread* thread) { jlong start_time_ns = 0; if (log_is_enabled(Debug, handshake, task)) { start_time_ns = os::javaTimeNanos(); @@ -236,80 +230,149 @@ name(), p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()), completion_time); } - // Use the semaphore to inform the VM thread that we have completed the operation - _done.signal(); + // Inform VMThread/Handshaker that we have completed the operation. + // When this is executed by the Handshakee we need a release store + // here to make sure memory operations executed in the handshake + // closure are visible to the VMThread/Handshaker after it reads + // that the operation has completed. + Atomic::dec(&_pending_threads, memory_order_release); - // It is no longer safe to refer to 'this' as the VMThread may have destroyed this operation + // It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation } void Handshake::execute(HandshakeClosure* thread_cl) { - HandshakeThreadsOperation cto(thread_cl); + HandshakeOperation cto(thread_cl); VM_HandshakeAllThreads handshake(&cto); VMThread::execute(&handshake); } bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) { - HandshakeThreadsOperation cto(thread_cl); + HandshakeOperation cto(thread_cl); VM_HandshakeOneThread handshake(&cto, target); VMThread::execute(&handshake); return handshake.executed(); } -HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) { - DEBUG_ONLY(_vmthread_processing_handshake = false;) +bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) { + JavaThread* self = JavaThread::current(); + HandshakeOperation op(thread_cl, /*is_direct*/ true); + + jlong start_time_ns = 0; + if (log_is_enabled(Info, handshake)) { + start_time_ns = os::javaTimeNanos(); + } + + ThreadsListHandle tlh; + if (tlh.includes(target)) { + target->set_handshake_operation(&op); + } else { + log_handshake_info(start_time_ns, op.name(), 0, 0, "(thread dead)"); + return false; + } + + bool by_handshaker = false; + while (!op.is_completed()) { + by_handshaker = target->handshake_try_process(&op); + // Check for pending handshakes to avoid possible deadlocks where our + // target is trying to handshake us. + if (SafepointMechanism::should_block(self)) { + ThreadBlockInVM tbivm(self); + } + } + + // This pairs up with the release store in do_handshake(). It prevents future + // loads from floating above the load of _pending_threads in is_completed() + // and thus prevents reading stale data modified in the handshake closure + // by the Handshakee. + OrderAccess::acquire(); + + log_handshake_info(start_time_ns, op.name(), 1, by_handshaker ? 1 : 0); + + return op.executed(); } -void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) { - _operation = op; - SafepointMechanism::arm_local_poll_release(target); -} - -void HandshakeState::clear_handshake(JavaThread* target) { - _operation = NULL; - SafepointMechanism::disarm_if_needed(target, true /* release */); +HandshakeState::HandshakeState() : + _operation(NULL), + _operation_direct(NULL), + _handshake_turn_sem(1), + _processing_sem(1), + _thread_in_process_handshake(false) +{ + DEBUG_ONLY(_active_handshaker = NULL;) } -void HandshakeState::process_self_inner(JavaThread* thread) { - assert(Thread::current() == thread, "should call from thread"); - assert(!thread->is_terminated(), "should not be a terminated thread"); - assert(thread->thread_state() != _thread_blocked, "should not be in a blocked state"); - assert(thread->thread_state() != _thread_in_native, "should not be in native"); +void HandshakeState::set_operation(HandshakeOperation* op) { + if (!op->is_direct()) { + assert(Thread::current()->is_VM_thread(), "should be the VMThread"); + _operation = op; + } else { + assert(Thread::current()->is_Java_thread(), "should be a JavaThread"); + // Serialize direct handshakes so that only one proceeds at a time for a given target + _handshake_turn_sem.wait_with_safepoint_check(JavaThread::current()); + _operation_direct = op; + } + SafepointMechanism::arm_local_poll_release(_handshakee); +} + +void HandshakeState::clear_handshake(bool is_direct) { + if (!is_direct) { + _operation = NULL; + } else { + _operation_direct = NULL; + _handshake_turn_sem.signal(); + } +} + +void HandshakeState::process_self_inner() { + assert(Thread::current() == _handshakee, "should call from _handshakee"); + assert(!_handshakee->is_terminated(), "should not be a terminated thread"); + assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state"); + assert(_handshakee->thread_state() != _thread_in_native, "should not be in native"); + JavaThread* self = _handshakee; do { - ThreadInVMForHandshake tivm(thread); - if (!_semaphore.trywait()) { - _semaphore.wait_with_safepoint_check(thread); + ThreadInVMForHandshake tivm(self); + if (!_processing_sem.trywait()) { + _processing_sem.wait_with_safepoint_check(self); } - HandshakeOperation* op = Atomic::load_acquire(&_operation); - if (op != NULL) { - HandleMark hm(thread); - CautiouslyPreserveExceptionMark pem(thread); - // Disarm before execute the operation - clear_handshake(thread); - op->do_handshake(thread); + if (has_operation()) { + HandleMark hm(self); + CautiouslyPreserveExceptionMark pem(self); + HandshakeOperation * op = _operation; + if (op != NULL) { + // Disarm before executing the operation + clear_handshake(/*is_direct*/ false); + op->do_handshake(self); + } + op = _operation_direct; + if (op != NULL) { + // Disarm before executing the operation + clear_handshake(/*is_direct*/ true); + op->do_handshake(self); + } } - _semaphore.signal(); + _processing_sem.signal(); } while (has_operation()); } -bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) { +bool HandshakeState::can_process_handshake() { // handshake_safe may only be called with polls armed. - // VM thread controls this by first claiming the handshake via claim_handshake_for_vmthread. - return SafepointSynchronize::handshake_safe(target); + // Handshaker controls this by first claiming the handshake via claim_handshake(). + return SafepointSynchronize::handshake_safe(_handshakee); } -static bool possibly_vmthread_can_process_handshake(JavaThread* target) { +bool HandshakeState::possibly_can_process_handshake() { // Note that this method is allowed to produce false positives. - if (target->is_ext_suspended()) { + if (_handshakee->is_ext_suspended()) { return true; } - if (target->is_terminated()) { + if (_handshakee->is_terminated()) { return true; } - switch (target->thread_state()) { + switch (_handshakee->thread_state()) { case _thread_in_native: // native threads are safe if they have no java stack or have walkable stack - return !target->has_last_Java_frame() || target->frame_anchor()->walkable(); + return !_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(); case _thread_blocked: return true; @@ -319,32 +382,40 @@ } } -bool HandshakeState::claim_handshake_for_vmthread() { - if (!_semaphore.trywait()) { +bool HandshakeState::claim_handshake(bool is_direct) { + if (!_processing_sem.trywait()) { return false; } - if (has_operation()) { + if (has_specific_operation(is_direct)){ return true; } - _semaphore.signal(); + _processing_sem.signal(); return false; } -bool HandshakeState::try_process_by_vmThread(JavaThread* target) { - assert(Thread::current()->is_VM_thread(), "should call from vm thread"); +bool HandshakeState::try_process(HandshakeOperation* op) { + bool is_direct = op->is_direct(); - if (!has_operation()) { + if (!has_specific_operation(is_direct)){ // JT has already cleared its handshake return false; } - if (!possibly_vmthread_can_process_handshake(target)) { + if (!possibly_can_process_handshake()) { // JT is observed in an unsafe state, it must notice the handshake itself return false; } // Claim the semaphore if there still an operation to be executed. - if (!claim_handshake_for_vmthread()) { + if (!claim_handshake(is_direct)) { + return false; + } + + // Check if the handshake operation is the same as the one we meant to execute. The + // handshake could have been already processed by the handshakee and a new handshake + // by another JavaThread might be in progress. + if (is_direct && op != _operation_direct) { + _processing_sem.signal(); return false; } @@ -352,19 +423,19 @@ // can observe a safe state the thread cannot possibly continue without // getting caught by the semaphore. bool executed = false; - if (vmthread_can_process_handshake(target)) { - guarantee(!_semaphore.trywait(), "we should already own the semaphore"); - log_trace(handshake)("Processing handshake by VMThtread"); - DEBUG_ONLY(_vmthread_processing_handshake = true;) - _operation->do_handshake(target); - DEBUG_ONLY(_vmthread_processing_handshake = false;) - // Disarm after VM thread have executed the operation. - clear_handshake(target); + if (can_process_handshake()) { + guarantee(!_processing_sem.trywait(), "we should already own the semaphore"); + log_trace(handshake)("Processing handshake by %s", Thread::current()->is_VM_thread() ? "VMThread" : "Handshaker"); + DEBUG_ONLY(_active_handshaker = Thread::current();) + op->do_handshake(_handshakee); + DEBUG_ONLY(_active_handshaker = NULL;) + // Disarm after we have executed the operation. + clear_handshake(is_direct); executed = true; } // Release the thread - _semaphore.signal(); + _processing_sem.signal(); return executed; }
--- a/src/hotspot/share/runtime/handshake.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/handshake.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * 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,13 +30,17 @@ #include "runtime/flags/flagSetting.hpp" #include "runtime/semaphore.hpp" +class HandshakeOperation; class JavaThread; // A handshake closure is a callback that is executed for each JavaThread // while that thread is in a safepoint safe state. The callback is executed -// either by the thread itself or by the VM thread while keeping the thread -// in a blocked state. A handshake can be performed with a single -// JavaThread as well. +// either by the target JavaThread itself or by the VMThread while keeping +// the target thread in a blocked state. A handshake can be performed with a +// single JavaThread as well. In that case, the callback is executed either +// by the target JavaThread itself or, depending on whether the operation is +// a direct handshake or not, by the JavaThread that requested the handshake +// or the VMThread respectively. class HandshakeClosure : public ThreadClosure { const char* const _name; public: @@ -52,47 +56,51 @@ // Execution of handshake operation static void execute(HandshakeClosure* hs_cl); static bool execute(HandshakeClosure* hs_cl, JavaThread* target); + static bool execute_direct(HandshakeClosure* hs_cl, JavaThread* target); }; -class HandshakeOperation; +// The HandshakeState keeps track of an ongoing handshake for this JavaThread. +// VMThread/Handshaker and JavaThread are serialized with semaphore _processing_sem +// making sure the operation is only done by either VMThread/Handshaker on behalf +// of the JavaThread or by the target JavaThread itself. +class HandshakeState { + JavaThread* _handshakee; + HandshakeOperation* volatile _operation; + HandshakeOperation* volatile _operation_direct; -// The HandshakeState keep tracks of an ongoing handshake for one JavaThread. -// VM thread and JavaThread are serialized with the semaphore making sure -// the operation is only done by either VM thread on behalf of the JavaThread -// or the JavaThread itself. -class HandshakeState { - HandshakeOperation* volatile _operation; - - Semaphore _semaphore; + Semaphore _handshake_turn_sem; // Used to serialize direct handshakes for this JavaThread. + Semaphore _processing_sem; bool _thread_in_process_handshake; - bool claim_handshake_for_vmthread(); - bool vmthread_can_process_handshake(JavaThread* target); + bool claim_handshake(bool is_direct); + bool possibly_can_process_handshake(); + bool can_process_handshake(); + void clear_handshake(bool is_direct); - void clear_handshake(JavaThread* thread); + void process_self_inner(); - void process_self_inner(JavaThread* thread); public: HandshakeState(); - void set_operation(JavaThread* thread, HandshakeOperation* op); + void set_handshakee(JavaThread* thread) { _handshakee = thread; } - bool has_operation() const { - return _operation != NULL; + void set_operation(HandshakeOperation* op); + bool has_operation() const { return _operation != NULL || _operation_direct != NULL; } + bool has_specific_operation(bool is_direct) const { + return is_direct ? _operation_direct != NULL : _operation != NULL; } - void process_by_self(JavaThread* thread) { + void process_by_self() { if (!_thread_in_process_handshake) { FlagSetting fs(_thread_in_process_handshake, true); - process_self_inner(thread); + process_self_inner(); } } - - bool try_process_by_vmThread(JavaThread* target); + bool try_process(HandshakeOperation* op); #ifdef ASSERT - bool _vmthread_processing_handshake; - bool is_vmthread_processing_handshake() const { return _vmthread_processing_handshake; } + Thread* _active_handshaker; + Thread* active_handshaker() const { return _active_handshaker; } #endif };
--- a/src/hotspot/share/runtime/mutexLocker.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/mutexLocker.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -188,7 +188,7 @@ } void assert_locked_or_safepoint_or_handshake(const Mutex* lock, const JavaThread* thread) { - if (Thread::current()->is_VM_thread() && thread->is_vmthread_processing_handshake()) return; + if (Thread::current() == thread->active_handshaker()) return; assert_locked_or_safepoint(lock); } #endif
--- a/src/hotspot/share/runtime/safepoint.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/safepoint.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -463,8 +463,6 @@ assert(!cur_state->is_running(), "Thread not suspended at safepoint"); cur_state->restart(); // TSS _running assert(cur_state->is_running(), "safepoint state has not been reset"); - - SafepointMechanism::disarm_if_needed(current, false /* NO release */); } } // ~JavaThreadIteratorWithHandle @@ -705,7 +703,6 @@ } bool SafepointSynchronize::handshake_safe(JavaThread *thread) { - assert(Thread::current()->is_VM_thread(), "Must be VMThread"); if (thread->is_ext_suspended() || thread->is_terminated()) { return true; }
--- a/src/hotspot/share/runtime/safepointMechanism.inline.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/safepointMechanism.inline.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -66,19 +66,6 @@ thread->set_polling_page(poll_disarmed_value()); } -void SafepointMechanism::disarm_if_needed(JavaThread* thread, bool memory_order_release) { - JavaThreadState jts = thread->thread_state(); - if (jts == _thread_in_native || jts == _thread_in_native_trans) { - // JavaThread will disarm itself and execute cross_modify_fence() before continuing - return; - } - if (memory_order_release) { - thread->set_polling_page_release(poll_disarmed_value()); - } else { - thread->set_polling_page(poll_disarmed_value()); - } -} - void SafepointMechanism::arm_local_poll_release(JavaThread* thread) { thread->set_polling_page_release(poll_armed_value()); }
--- a/src/hotspot/share/runtime/thread.cpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/thread.cpp Fri Apr 10 17:10:22 2020 +0000 @@ -1690,6 +1690,7 @@ _SleepEvent = ParkEvent::Allocate(this); // Setup safepoint state info for this thread ThreadSafepointState::create(this); + _handshake.set_handshakee(this); debug_only(_java_call_counter = 0); @@ -4465,12 +4466,21 @@ // exit_globals() will delete tty exit_globals(); - // We are after VM_Exit::set_vm_exited() so we can't call - // thread->smr_delete() or we will block on the Threads_lock. - // Deleting the shutdown thread here is safe because another - // JavaThread cannot have an active ThreadsListHandle for - // this JavaThread. - delete thread; + // We are here after VM_Exit::set_vm_exited() so we can't call + // thread->smr_delete() or we will block on the Threads_lock. We + // must check that there are no active references to this thread + // before attempting to delete it. A thread could be waiting on + // _handshake_turn_sem trying to execute a direct handshake with + // this thread. + if (!ThreadsSMRSupport::is_a_protected_JavaThread(thread)) { + delete thread; + } else { + // Clear value for _thread_key in TLS to prevent, depending + // on pthreads implementation, possible execution of + // thread-specific destructor in infinite loop at thread + // exit. + Thread::clear_thread_current(); + } #if INCLUDE_JVMCI if (JVMCICounterSize > 0) {
--- a/src/hotspot/share/runtime/thread.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/thread.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -1348,7 +1348,7 @@ HandshakeState _handshake; public: void set_handshake_operation(HandshakeOperation* op) { - _handshake.set_operation(this, op); + _handshake.set_operation(op); } bool has_handshake() const { @@ -1356,16 +1356,16 @@ } void handshake_process_by_self() { - _handshake.process_by_self(this); + _handshake.process_by_self(); } - bool handshake_try_process_by_vmThread() { - return _handshake.try_process_by_vmThread(this); + bool handshake_try_process(HandshakeOperation* op) { + return _handshake.try_process(op); } #ifdef ASSERT - bool is_vmthread_processing_handshake() const { - return _handshake.is_vmthread_processing_handshake(); + Thread* active_handshaker() const { + return _handshake.active_handshaker(); } #endif
--- a/src/hotspot/share/runtime/threadSMR.hpp Tue Apr 07 18:30:32 2020 +0000 +++ b/src/hotspot/share/runtime/threadSMR.hpp Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * 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,7 +129,6 @@ static void inc_deleted_thread_cnt(); static void inc_java_thread_list_alloc_cnt(); static void inc_tlh_cnt(); - static bool is_a_protected_JavaThread(JavaThread *thread); static void release_stable_list_wake_up(bool is_nested); static void set_delete_notify(); static void threads_do(ThreadClosure *tc); @@ -143,6 +142,7 @@ public: static void add_thread(JavaThread *thread); static ThreadsList* get_java_thread_list(); + static bool is_a_protected_JavaThread(JavaThread *thread); static bool is_a_protected_JavaThread_with_lock(JavaThread *thread); static bool is_bootstrap_list(ThreadsList* list); static void remove_thread(JavaThread *thread);
--- a/src/java.base/linux/native/libnio/ch/EPoll.c Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/linux/native/libnio/ch/EPoll.c Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * 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,10 +57,9 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_EPoll_create(JNIEnv *env, jclass clazz) { - /* size hint not used in modern kernels */ - int epfd = epoll_create(256); + int epfd = epoll_create1(EPOLL_CLOEXEC); if (epfd < 0) { - JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed"); + JNU_ThrowIOExceptionWithLastError(env, "epoll_create1 failed"); } return epfd; }
--- a/src/java.base/share/classes/java/io/DataOutput.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/io/DataOutput.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,8 +113,8 @@ void writeBoolean(boolean v) throws IOException; /** - * Writes to the output stream the eight low- - * order bits of the argument {@code v}. + * Writes to the output stream the eight low-order + * bits of the argument {@code v}. * The 24 high-order bits of {@code v} * are ignored. (This means that {@code writeByte} * does exactly the same thing as {@code write} @@ -140,7 +140,7 @@ * }</pre> <p> * The bytes written by this method may be * read by the {@code readShort} method - * of interface {@code DataInput} , which + * of interface {@code DataInput}, which * will then return a {@code short} equal * to {@code (short)v}. * @@ -161,7 +161,7 @@ * }</pre><p> * The bytes written by this method may be * read by the {@code readChar} method - * of interface {@code DataInput} , which + * of interface {@code DataInput}, which * will then return a {@code char} equal * to {@code (char)v}. * @@ -183,7 +183,7 @@ * }</pre><p> * The bytes written by this method may be read * by the {@code readInt} method of interface - * {@code DataInput} , which will then + * {@code DataInput}, which will then * return an {@code int} equal to {@code v}. * * @param v the {@code int} value to be written. @@ -208,7 +208,7 @@ * }</pre><p> * The bytes written by this method may be * read by the {@code readLong} method - * of interface {@code DataInput} , which + * of interface {@code DataInput}, which * will then return a {@code long} equal * to {@code v}. * @@ -343,7 +343,7 @@ * string {@code s} is written.<p> The * bytes written by this method may be read * by the {@code readUTF} method of interface - * {@code DataInput} , which will then + * {@code DataInput}, which will then * return a {@code String} equal to {@code s}. * * @param s the string value to be written.
--- a/src/java.base/share/classes/java/lang/Character.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/Character.java Fri Apr 10 17:10:22 2020 +0000 @@ -242,7 +242,7 @@ * General category "Nd" in the Unicode specification. * @since 1.1 */ - public static final byte DECIMAL_DIGIT_NUMBER = 9; + public static final byte DECIMAL_DIGIT_NUMBER = 9; /** * General category "Nl" in the Unicode specification. @@ -11072,7 +11072,7 @@ * Note: if the specified character is not assigned a name by * the <i>UnicodeData</i> file (part of the Unicode Character * Database maintained by the Unicode Consortium), the returned - * name is the same as the result of expression. + * name is the same as the result of expression: * * <blockquote>{@code * Character.UnicodeBlock.of(codePoint).toString().replace('_', ' ') @@ -11116,7 +11116,7 @@ * <p> * Note: if a character is not assigned a name by the <i>UnicodeData</i> * file (part of the Unicode Character Database maintained by the Unicode - * Consortium), its name is defined as the result of expression + * Consortium), its name is defined as the result of expression: * * <blockquote>{@code * Character.UnicodeBlock.of(codePoint).toString().replace('_', ' ')
--- a/src/java.base/share/classes/java/lang/Class.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/Class.java Fri Apr 10 17:10:22 2020 +0000 @@ -144,7 +144,7 @@ * For example: * * <blockquote> - * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());} + * {@code System.out.println("The name of class Foo is: " + Foo.class.getName());} * </blockquote> * * @param <T> the type of the class modeled by this {@code Class} @@ -207,7 +207,7 @@ * The string is formatted as a list of type modifiers, if any, * followed by the kind of type (empty string for primitive types * and {@code class}, {@code enum}, {@code interface}, - * <code>@</code>{@code interface}, or {@code record} as appropriate), followed + * {@code @interface}, or {@code record} as appropriate), followed * by the type's name, followed by an angle-bracketed * comma-separated list of the type's type parameters, if any, * including informative bounds on the type parameters, if any. @@ -3779,9 +3779,14 @@ } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override @SuppressWarnings("unchecked") public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { Objects.requireNonNull(annotationClass); @@ -3800,6 +3805,10 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3814,13 +3823,22 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return AnnotationParser.toArray(annotationData().annotations); } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3833,6 +3851,10 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3845,8 +3867,13 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(annotationData().declaredAnnotations); }
--- a/src/java.base/share/classes/java/lang/FdLibm.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/FdLibm.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -237,8 +237,8 @@ // floating-point divide. Splitting a floating-point // number into non-overlapping portions can be // accomplished by judicious use of multiplies and - // additions. For details see T. J. Dekker, A Floating - // Point Technique for Extending the Available Precision , + // additions. For details see T. J. Dekker, A Floating-Point + // Technique for Extending the Available Precision, // Numerische Mathematik, vol. 18, 1971, pp.224-242 and // subsequent work.
--- a/src/java.base/share/classes/java/lang/Module.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/Module.java Fri Apr 10 17:10:22 2020 +0000 @@ -1381,6 +1381,9 @@ /** * {@inheritDoc} * This method returns {@code null} when invoked on an unnamed module. + * + * <p> Note that any annotation returned by this method is a + * declaration annotation. */ @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { @@ -1390,6 +1393,9 @@ /** * {@inheritDoc} * This method returns an empty array when invoked on an unnamed module. + * + * <p> Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getAnnotations() { @@ -1399,6 +1405,9 @@ /** * {@inheritDoc} * This method returns an empty array when invoked on an unnamed module. + * + * <p> Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getDeclaredAnnotations() {
--- a/src/java.base/share/classes/java/lang/Package.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/Package.java Fri Apr 10 17:10:22 2020 +0000 @@ -434,9 +434,14 @@ } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { return getPackageInfo().getAnnotation(annotationClass); } @@ -452,6 +457,10 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -461,13 +470,21 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return getPackageInfo().getAnnotations(); } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -486,8 +503,12 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return getPackageInfo().getDeclaredAnnotations(); }
--- a/src/java.base/share/classes/java/lang/Runtime.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/Runtime.java Fri Apr 10 17:10:22 2020 +0000 @@ -757,8 +757,8 @@ * for more details. * * Otherwise, the libname argument is loaded from a system library - * location and mapped to a native library image in an implementation- - * dependent manner. + * location and mapped to a native library image in an + * implementation-dependent manner. * <p> * First, if there is a security manager, its {@code checkLink} * method is called with the {@code libname} as its argument.
--- a/src/java.base/share/classes/java/lang/String.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/String.java Fri Apr 10 17:10:22 2020 +0000 @@ -2063,9 +2063,9 @@ * <blockquote> * <code> * {@link java.util.regex.Pattern}.{@link - * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link + * java.util.regex.Pattern#compile(String) compile}(<i>regex</i>).{@link * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link - * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>) + * java.util.regex.Matcher#replaceFirst(String) replaceFirst}(<i>repl</i>) * </code> * </blockquote> * @@ -2108,9 +2108,9 @@ * <blockquote> * <code> * {@link java.util.regex.Pattern}.{@link - * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link + * java.util.regex.Pattern#compile(String) compile}(<i>regex</i>).{@link * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link - * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>) + * java.util.regex.Matcher#replaceAll(String) replaceAll}(<i>repl</i>) * </code> * </blockquote> * @@ -2275,7 +2275,7 @@ * <blockquote> * <code> * {@link java.util.regex.Pattern}.{@link - * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link + * java.util.regex.Pattern#compile(String) compile}(<i>regex</i>).{@link * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>, <i>n</i>) * </code> * </blockquote> @@ -2973,8 +2973,6 @@ * @since 13 * */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.TEXT_BLOCKS, - essentialAPI=true) public String stripIndent() { int length = length(); if (length == 0) { @@ -3107,8 +3105,6 @@ * * @since 13 */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.TEXT_BLOCKS, - essentialAPI=true) public String translateEscapes() { if (isEmpty()) { return ""; @@ -3369,8 +3365,6 @@ * @since 13 * */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.TEXT_BLOCKS, - essentialAPI=true) public String formatted(Object... args) { return new Formatter().format(this, args).toString(); }
--- a/src/java.base/share/classes/java/lang/System.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/System.java Fri Apr 10 17:10:22 2020 +0000 @@ -1863,8 +1863,8 @@ * for more details. * * Otherwise, the libname argument is loaded from a system library - * location and mapped to a native library image in an implementation- - * dependent manner. + * location and mapped to a native library image in an + * implementation-dependent manner. * <p> * The call {@code System.loadLibrary(name)} is effectively * equivalent to the call
--- a/src/java.base/share/classes/java/lang/annotation/ElementType.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/annotation/ElementType.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * 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,8 +33,8 @@ * given type. * * <p>The syntactic locations where annotations may appear are split into - * <em>declaration contexts</em> , where annotations apply to declarations, and - * <em>type contexts</em> , where annotations apply to types used in + * <em>declaration contexts</em>, where annotations apply to declarations, and + * <em>type contexts</em>, where annotations apply to types used in * declarations and expressions. * * <p>The constants {@link #ANNOTATION_TYPE}, {@link #CONSTRUCTOR}, {@link
--- a/src/java.base/share/classes/java/lang/annotation/Target.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/annotation/Target.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ * constants of {@link ElementType java.lang.annotation.ElementType}. * * <p>If an {@code @Target} meta-annotation is not present on an annotation type - * {@code T} , then an annotation of type {@code T} may be written as a + * {@code T}, then an annotation of type {@code T} may be written as a * modifier for any declaration except a type parameter declaration. * * <p>If an {@code @Target} meta-annotation is present, the compiler will enforce
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -509,15 +509,22 @@ new ReflectionFactory.GetReflectionFactoryAction()); /** + * {@inheritDoc} + * + * <p> Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { throw new AssertionError("All subclasses should override this method"); } /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ @@ -527,6 +534,11 @@ } /** + * {@inheritDoc} + * + * <p> Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -536,13 +548,24 @@ } /** + * {@inheritDoc} + * + * <p> Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return getDeclaredAnnotations(); } /** + * {@inheritDoc} + * + * <p> Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -555,6 +578,11 @@ } /** + * {@inheritDoc} + * + * <p> Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -567,8 +595,14 @@ } /** + * {@inheritDoc} + * + * <p> Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { throw new AssertionError("All subclasses should override this method"); }
--- a/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java Fri Apr 10 17:10:22 2020 +0000 @@ -38,20 +38,38 @@ import sun.reflect.annotation.AnnotationType; /** - * Represents an annotated element of the program currently running in this - * VM. This interface allows annotations to be read reflectively. All + * Represents an annotated construct of the program currently running + * in this VM. + * + * A construct is either an element or a type. Annotations on an + * element are on a <em>declaration</em>, whereas annotations on a + * type are on a specific <em>use</em> of a type name. + * + * As defined by <cite>The Java™ Language Specification</cite> + * section {@jls 9.7.4}, an annotation on an element is a + * <em>declaration annotation</em> and an annotation on a type is a + * <em>type annotation</em>. + * + * Note that any annotations returned by methods on the {@link + * AnnotatedType AnnotatedType} interface and its subinterfaces are + * type annotations as the entity being potentially annotated is a + * type. Annotations returned by methods outside of the {@code + * AnnotatedType} hierarchy are declaration annotations. + * + * <p>This interface allows annotations to be read reflectively. All * annotations returned by methods in this interface are immutable and - * serializable. The arrays returned by methods of this interface may be modified - * by callers without affecting the arrays returned to other callers. + * serializable. The arrays returned by methods of this interface may + * be modified by callers without affecting the arrays returned to + * other callers. * * <p>The {@link #getAnnotationsByType(Class)} and {@link * #getDeclaredAnnotationsByType(Class)} methods support multiple * annotations of the same type on an element. If the argument to - * either method is a repeatable annotation type (JLS 9.6), then the - * method will "look through" a container annotation (JLS 9.7), if - * present, and return any annotations inside the container. Container - * annotations may be generated at compile-time to wrap multiple - * annotations of the argument type. + * either method is a repeatable annotation type (JLS {@jls 9.6}), + * then the method will "look through" a container annotation (JLS + * {@jls 9.7}), if present, and return any annotations inside the + * container. Container annotations may be generated at compile-time + * to wrap multiple annotations of the argument type. * * <p>The terms <em>directly present</em>, <em>indirectly present</em>, * <em>present</em>, and <em>associated</em> are used throughout this @@ -260,8 +278,8 @@ * <p>The truth value returned by this method is equivalent to: * {@code getAnnotation(annotationClass) != null} * - * <p>The body of the default method is specified to be the code - * above. + * @implSpec The default implementation returns {@code + * getAnnotation(annotationClass) != null}. * * @param annotationClass the Class object corresponding to the * annotation type @@ -310,7 +328,7 @@ * * The difference between this method and {@link #getAnnotation(Class)} * is that this method detects if its argument is a <em>repeatable - * annotation type</em> (JLS 9.6), and if so, attempts to find one or + * annotation type</em> (JLS {@jls 9.6}), and if so, attempts to find one or * more annotations of that type by "looking through" a container * annotation. * @@ -406,7 +424,7 @@ * * The difference between this method and {@link * #getDeclaredAnnotation(Class)} is that this method detects if its - * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so, + * argument is a <em>repeatable annotation type</em> (JLS {@jls 9.6}), and if so, * attempts to find one or more annotations of that type by "looking * through" a container annotation if one is present. *
--- a/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * 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,12 +25,18 @@ package java.lang.reflect; +import java.lang.annotation.Annotation; + /** * {@code AnnotatedType} represents the potentially annotated use of a type in * the program currently running in this VM. The use may be of any type in the * Java programming language, including an array type, a parameterized type, a * type variable, or a wildcard type. * + * Note that any annotations returned by methods on this interface are + * <em>type annotations</em> (JLS {@jls 9.7.4}) as the entity being + * potentially annotated is a type. + * * @since 1.8 */ public interface AnnotatedType extends AnnotatedElement { @@ -72,4 +78,30 @@ * @return the type this annotated type represents */ public Type getType(); + + /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a type + * annotation. + * + * @throws NullPointerException {@inheritDoc} + */ + @Override + <T extends Annotation> T getAnnotation(Class<T> annotationClass); + + /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are type + * annotations. + */ + @Override + Annotation[] getAnnotations(); + + /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are type + * annotations. + */ + @Override + Annotation[] getDeclaredAnnotations(); }
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -576,9 +576,11 @@ /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { return super.getAnnotation(annotationClass); } @@ -587,6 +589,7 @@ * {@inheritDoc} * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return super.getDeclaredAnnotations(); }
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Executable.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -544,6 +544,9 @@ * ("synthetic") to the parameter list for a method. See {@link * java.lang.reflect.Parameter} for more information. * + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @see java.lang.reflect.Parameter * @see java.lang.reflect.Parameter#getAnnotations * @return an array of arrays that represent the annotations on @@ -577,6 +580,7 @@ * {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -584,6 +588,7 @@ /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -596,6 +601,7 @@ /** * {@inheritDoc} */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); }
--- a/src/java.base/share/classes/java/lang/reflect/Field.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Field.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1132,9 +1132,12 @@ } /** + * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -1142,6 +1145,7 @@ /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -1155,6 +1159,7 @@ /** * {@inheritDoc} */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); }
--- a/src/java.base/share/classes/java/lang/reflect/Method.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Method.java Fri Apr 10 17:10:22 2020 +0000 @@ -686,9 +686,10 @@ /** * {@inheritDoc} - * @throws NullPointerException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { return super.getAnnotation(annotationClass); } @@ -697,6 +698,7 @@ * {@inheritDoc} * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return super.getDeclaredAnnotations(); }
--- a/src/java.base/share/classes/java/lang/reflect/Modifier.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Modifier.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -377,7 +377,7 @@ /** * The Java source modifiers that can be applied to a method. - * @jls8.4.3 Method Modifiers + * @jls 8.4.3 Method Modifiers */ private static final int METHOD_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | @@ -400,9 +400,6 @@ private static final int PARAMETER_MODIFIERS = Modifier.FINAL; - /** - * - */ static final int ACCESS_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
--- a/src/java.base/share/classes/java/lang/reflect/Parameter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/Parameter.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ * @param obj The object to compare. * @return Whether or not this is equal to the argument. */ + @Override public boolean equals(Object obj) { if(obj instanceof Parameter) { Parameter other = (Parameter)obj; @@ -90,6 +91,7 @@ * * @return A hash code based on the executable's hash code. */ + @Override public int hashCode() { return executable.hashCode() ^ index; } @@ -111,7 +113,7 @@ * Returns a string describing this parameter. The format is the * modifiers for the parameter, if any, in canonical order as * recommended by <cite>The Java™ Language - * Specification</cite>, followed by the fully- qualified type of + * Specification</cite>, followed by the fully-qualified type of * the parameter (excluding the last [] if the parameter is * variable arity), followed by "..." if the parameter is variable * arity, followed by a space, followed by the name of the @@ -120,6 +122,7 @@ * @return A string representation of the parameter and associated * information. */ + @Override public String toString() { final StringBuilder sb = new StringBuilder(); final Type type = getParameterizedType(); @@ -280,8 +283,11 @@ /** * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. * @throws NullPointerException {@inheritDoc} */ + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -289,6 +295,9 @@ /** * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -300,14 +309,22 @@ /** * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. */ + @Override public Annotation[] getDeclaredAnnotations() { return executable.getParameterAnnotations()[index]; } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} */ + @Override public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { // Only annotations on classes are inherited, for all other // objects getDeclaredAnnotation is the same as @@ -316,6 +333,10 @@ } /** + * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -328,7 +349,10 @@ /** * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. */ + @Override public Annotation[] getAnnotations() { return getDeclaredAnnotations(); }
--- a/src/java.base/share/classes/java/lang/reflect/RecordComponent.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/lang/reflect/RecordComponent.java Fri Apr 10 17:10:22 2020 +0000 @@ -180,6 +180,9 @@ } /** + * {@inheritDoc} + * <p>Note that any annotation returned by this method is a + * declaration annotation. * @throws NullPointerException {@inheritDoc} */ @Override @@ -215,6 +218,8 @@ /** * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getAnnotations() { @@ -223,6 +228,8 @@ /** * {@inheritDoc} + * <p>Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); }
--- a/src/java.base/share/classes/java/math/BigDecimal.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/math/BigDecimal.java Fri Apr 10 17:10:22 2020 +0000 @@ -104,7 +104,7 @@ * determines how any discarded trailing digits affect the returned * result. * - * <p>For all arithmetic operators , the operation is carried out as + * <p>For all arithmetic operators, the operation is carried out as * though an exact intermediate result were first calculated and then * rounded to the number of digits specified by the precision setting * (if necessary), using the selected rounding mode. If the exact
--- a/src/java.base/share/classes/java/math/BigInteger.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/math/BigInteger.java Fri Apr 10 17:10:22 2020 +0000 @@ -80,8 +80,8 @@ * inclusive. * * <p>Bit operations operate on a single bit of the two's-complement - * representation of their operand. If necessary, the operand is sign- - * extended so that it contains the designated bit. None of the single-bit + * representation of their operand. If necessary, the operand is sign-extended + * so that it contains the designated bit. None of the single-bit * operations can produce a BigInteger with a different sign from the * BigInteger being operated on, as they affect only a single bit, and the * arbitrarily large abstraction provided by this class ensures that conceptually
--- a/src/java.base/share/classes/java/net/MulticastSocket.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/net/MulticastSocket.java Fri Apr 10 17:10:22 2020 +0000 @@ -698,8 +698,8 @@ } /** - * Sends a datagram packet to the destination, with a TTL (time- - * to-live) other than the default for the socket. This method + * Sends a datagram packet to the destination, with a TTL (time-to-live) + * other than the default for the socket. This method * need only be used in instances where a particular TTL is desired; * otherwise it is preferable to set a TTL once on the socket, and * use that default TTL for all packets. This method does <B>not
--- a/src/java.base/share/classes/java/text/DecimalFormatSymbols.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/text/DecimalFormatSymbols.java Fri Apr 10 17:10:22 2020 +0000 @@ -904,7 +904,7 @@ * the same as {@code decimalSeparator} and {@code exponential} * to be 'E'. * If {@code serialVersionOnStream} is less than 2, - * initializes {@code locale}to the root locale, and initializes + * initializes {@code locale} to the root locale, and initializes * If {@code serialVersionOnStream} is less than 3, it initializes * {@code exponentialSeparator} using {@code exponential}. * If {@code serialVersionOnStream} is less than 4, it initializes
--- a/src/java.base/share/classes/java/text/NumberFormat.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/text/NumberFormat.java Fri Apr 10 17:10:22 2020 +0000 @@ -865,7 +865,7 @@ * Sets the minimum number of digits allowed in the fraction portion of a * number. minimumFractionDigits must be ≤ maximumFractionDigits. If the * new value for minimumFractionDigits exceeds the current value - * of maximumFractionDigits, then maximumIntegerDigits will also be set to + * of maximumFractionDigits, then maximumFractionDigits will also be set to * the new value * * @param newValue the minimum number of fraction digits to be shown; if
--- a/src/java.base/share/classes/java/util/Calendar.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/util/Calendar.java Fri Apr 10 17:10:22 2020 +0000 @@ -235,7 +235,7 @@ * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH, * Calendar.SEPTEMBER)</code> sets the date to September 31, * 1999. This is a temporary internal representation that resolves to - * October 1, 1999 if {@code getTime()}is then called. However, a + * October 1, 1999 if {@code getTime()} is then called. However, a * call to {@code set(Calendar.DAY_OF_MONTH, 30)} before the call to * {@code getTime()} sets the date to September 30, 1999, since * no recomputation occurs after {@code set()} itself.</p>
--- a/src/java.base/share/classes/java/util/Formatter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/java/util/Formatter.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -767,7 +767,7 @@ * {@code toString()} method. * * <p> If the {@code '#'} flag is given and the argument is not a {@link - * Formattable} , then a {@link FormatFlagsConversionMismatchException} + * Formattable}, then a {@link FormatFlagsConversionMismatchException} * will be thrown. * * <tr><th scope="row" style="vertical-align:top"> {@code 'S'}
--- a/src/java.base/share/classes/jdk/internal/PreviewFeature.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/jdk/internal/PreviewFeature.java Fri Apr 10 17:10:22 2020 +0000 @@ -55,6 +55,12 @@ public enum Feature { PATTERN_MATCHING_IN_INSTANCEOF, + // 8242284: + // The TEXT_BLOCKS enum constant is not used in the JDK 15 codebase, but + // exists to support the bootcycle build of JDK 15. The bootcycle build + // of JDK 15 is performed with JDK 14 and the PreviewFeature type from + // JDK 15. Since the JDK 14 codebase uses the enum constant, it is + // necessary for PreviewFeature in JDK 15 to declare the enum constant. TEXT_BLOCKS, RECORDS, ;
--- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,7 +207,7 @@ /* * Verify if a member is public and memberClass is a public type * in a package that is unconditionally exported and - * return {@code true}if it is granted. + * return {@code true} if it is granted. * * @param memberClass the declaring class of the member being accessed * @param modifiers the member's access modifiers
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/ParserSAX.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/ParserSAX.java Fri Apr 10 17:10:22 2020 +0000 @@ -40,14 +40,14 @@ /** * XML non-validating push parser. - * - * This non-validating parser conforms to <a href="http://www.w3.org/TR/REC-xml" - * >Extensible Markup Language (XML) 1.0</a> and <a - * href="http://www.w3.org/TR/REC-xml-names" >"Namespaces in XML"</a> - * specifications. The API supported by the parser are <a - * href="http://java.sun.com/aboutJava/communityprocess/final/jsr030/index.html">CLDC - * 1.0</a> and <a href="http://www.jcp.org/en/jsr/detail?id=280">JSR-280</a>, a - * JavaME subset of <a href="http://java.sun.com/xml/jaxp/index.html">JAXP</a> + * <p> + * This non-validating parser conforms to <a href="http://www.w3.org/TR/REC-xml"> + * Extensible Markup Language (XML) 1.0</a> and + * <a href="http://www.w3.org/TR/REC-xml-names" >Namespaces in XML</a> + * specifications. The API supported by the parser are + * <a href="https://www.oracle.com/technetwork/java/cldc-141990.html">CLDC</a> and + * <a href="http://www.jcp.org/en/jsr/detail?id=280">JSR-280</a>, a JavaME subset of + * <a href="https://www.oracle.com/technetwork/java/intro-140052.html">JAXP</a> * and <a href="http://www.saxproject.org/">SAX2</a>. * * @see org.xml.sax.XMLReader
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1111,9 +1111,17 @@ * or has been closed, throw an Exception. */ private boolean checkEOF() throws IOException { - if (conContext.isInboundClosed()) { + if (conContext.isBroken) { + if (conContext.closeReason == null) { + return true; + } else { + throw new SSLException( + "Connection has closed: " + conContext.closeReason, + conContext.closeReason); + } + } else if (conContext.isInboundClosed()) { return true; - } else if (conContext.isInputCloseNotified || conContext.isBroken) { + } else if (conContext.isInputCloseNotified) { if (conContext.closeReason == null) { return true; } else {
--- a/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; /** @@ -236,8 +235,9 @@ result = Integer.parseInt(readLine()); if (result < 0 || result > (options.length - 1)) { result = defaultOption; + } else { + result = options[result].value; } - result = options[result].value; } catch (NumberFormatException e) { result = defaultOption; }
--- a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,9 @@ 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; +import sun.security.util.SecurityProperties; /** * Validator implementation built on the PKIX CertPath API. This @@ -62,14 +62,14 @@ .privilegedGetProperty("com.sun.net.ssl.checkRevocation"); /** - * 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. + * System or security 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"); + String prop = SecurityProperties + .privilegedGetOverridable("jdk.security.allowNonCaAnchor"); return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true")); }
--- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java Fri Apr 10 17:10:22 2020 +0000 @@ -1041,6 +1041,8 @@ case "RSA": return ifcFfcStrength(KeyUtil.getKeySize(k)) + "withRSA"; + case "RSASSA-PSS": + return "RSASSA-PSS"; default: return null; }
--- a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -35,6 +35,7 @@ import java.security.cert.X509CRLEntry; import java.security.cert.CRLException; import java.security.*; +import java.security.spec.AlgorithmParameterSpec; import java.util.*; import javax.security.auth.x500.X500Principal; @@ -495,10 +496,20 @@ else sigEngine = Signature.getInstance(algorithm, provider); - sigEngine.initSign(key); + AlgorithmParameterSpec params = AlgorithmId + .getDefaultAlgorithmParameterSpec(algorithm, key); + try { + SignatureUtil.initSignWithParam(sigEngine, key, params, null); + } catch (InvalidAlgorithmParameterException e) { + throw new SignatureException(e); + } - // in case the name is reset - sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm()); + if (params != null) { + sigAlgId = AlgorithmId.get(sigEngine.getParameters()); + } else { + // in case the name is reset + sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm()); + } infoSigAlgId = sigAlgId; DerOutputStream out = new DerOutputStream();
--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -601,11 +601,11 @@ SignatureUtil.initSignWithParam(sigEngine, key, signingParams, null); - // in case the name is reset if (signingParams != null) { algId = AlgorithmId.get(sigEngine.getParameters()); } else { - algId = AlgorithmId.get(algorithm); + // in case the name is reset + algId = AlgorithmId.get(sigEngine.getAlgorithm()); } DerOutputStream out = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream();
--- a/src/java.base/share/conf/security/java.security Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.base/share/conf/security/java.security Fri Apr 10 17:10:22 2020 +0000 @@ -1301,3 +1301,16 @@ # security property value defined here. # #jdk.security.krb5.default.initiate.credential=always-impersonate + +# +# Trust Anchor Certificates - CA Basic Constraint check +# +# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS +# connections) must have the cA Basic Constraint field set to 'true'. Also, if +# they include a Key Usage extension, the keyCertSign bit must be set. These +# checks, enabled by default, can be disabled for backward-compatibility +# purposes with the jdk.security.allowNonCaAnchor System and Security +# properties. In the case that both properties are simultaneously set, the +# System value prevails. The default value of the property is "false". +# +#jdk.security.allowNonCaAnchor=true \ No newline at end of file
--- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Fri Apr 10 17:10:22 2020 +0000 @@ -25,7 +25,6 @@ package javax.lang.model.util; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -246,13 +245,13 @@ * comment of an element. * * <p> A documentation comment of an element is a comment that - * begins with "{@code /**}" , ends with a separate + * begins with "{@code /**}", ends with a separate * "<code>*/</code>", and immediately precedes the element, * ignoring white space. Therefore, a documentation comment - * contains at least three"{@code *}" characters. The text + * contains at least three "{@code *}" characters. The text * returned for the documentation comment is a processed form of - * the comment as it appears in source code. The leading "{@code - * /**}" and trailing "<code>*/</code>" are removed. For lines + * the comment as it appears in source code. The leading "{@code /**}" + * and trailing "<code>*/</code>" are removed. For lines * of the comment starting after the initial "{@code /**}", * leading white space characters are discarded as are any * consecutive "{@code *}" characters appearing after the white @@ -382,7 +381,7 @@ */ EXPLICIT, - /** + /** * A mandated construct is one that is not explicitly declared * in the source code, but whose presence is mandated by the * specification. Such a construct is said to be implicitly @@ -403,7 +402,7 @@ */ MANDATED, - /** + /** * A synthetic construct is one that is neither implicitly nor * explicitly declared in the source code. Such a construct is * typically a translation artifact created by a compiler. @@ -414,8 +413,8 @@ * Returns {@code true} for values corresponding to constructs * that are implicitly or explicitly declared, {@code false} * otherwise. - * @return {@code true} for {@link EXPLICIT} and {@link - * MANDATED}, {@code false} otherwise. + * @return {@code true} for {@link #EXPLICIT} and {@link #MANDATED}, + * {@code false} otherwise. */ public boolean isDeclared() { return this != SYNTHETIC;
--- a/src/java.logging/share/classes/java/util/logging/Formatter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.logging/share/classes/java/util/logging/Formatter.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -334,19 +334,7 @@ } private static SSLParameters getDefaultParams(SSLContext ctx) { - SSLParameters params = ctx.getSupportedSSLParameters(); - String[] protocols = params.getProtocols(); - boolean found13 = false; - for (String proto : protocols) { - if (proto.equals("TLSv1.3")) { - found13 = true; - break; - } - } - if (found13) - params.setProtocols(new String[] {"TLSv1.3", "TLSv1.2"}); - else - params.setProtocols(new String[] {"TLSv1.2"}); + SSLParameters params = ctx.getDefaultSSLParameters(); return params; }
--- a/src/java.rmi/share/classes/java/rmi/server/Operation.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.rmi/share/classes/java/rmi/server/Operation.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * 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,8 +29,7 @@ * An <code>Operation</code> contains a description of a Java method. * <code>Operation</code> objects were used in JDK1.1 version stubs and * skeletons. The <code>Operation</code> class is not needed for 1.2 style - * stubs (stubs generated with <code>rmic -v1.2</code>); hence, this class - * is deprecated. + * stubs; hence, this class is deprecated. * * @since 1.1 * @deprecated no replacement
--- a/src/java.rmi/share/classes/java/rmi/server/Skeleton.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.rmi/share/classes/java/rmi/server/Skeleton.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * 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,11 +30,9 @@ * The <code>Skeleton</code> interface is used solely by the RMI * implementation. * - * <p> Every version 1.1 (and version 1.1 compatible skeletons generated in - * 1.2 using <code>rmic -vcompat</code>) skeleton class generated by the rmic - * stub compiler implements this interface. A skeleton for a remote object is - * a server-side entity that dispatches calls to the actual remote object - * implementation. + * <p> Every version 1.1 compatible skeleton implements this interface. + * A skeleton for a remote object is a server-side entity that dispatches calls + * to the actual remote object implementation. * * @author Ann Wollrath * @since 1.1
--- a/src/java.rmi/share/classes/java/rmi/server/SkeletonMismatchException.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.rmi/share/classes/java/rmi/server/SkeletonMismatchException.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * 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 @@ * remote method names or signatures in this interface have changed or * that the stub class used to make the call and the skeleton * receiving the call were not generated by the same version of - * the stub compiler (<code>rmic</code>). + * the stub protocol. * * @author Roger Riggs * @since 1.1
--- a/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,17 +32,14 @@ /** * Used for exporting a remote object with JRMP and obtaining a stub - * that communicates to the remote object. Stubs are either generated - * at runtime using dynamic proxy objects, or they are generated statically - * at build time, typically using the {@code rmic} tool. + * that communicates to the remote object. Stubs are generated + * at runtime using dynamic proxy objects. * * <p><strong>Deprecated: Static Stubs.</strong> <em>Support for statically * generated stubs is deprecated. This includes the API in this class that * requires the use of static stubs, as well as the runtime support for * loading static stubs. Generating stubs dynamically is preferred, using one - * of the non-deprecated ways of exporting objects as listed below. Do - * not run {@code rmic} to generate static stub classes. It is unnecessary, and - * it is also deprecated.</em> + * of the non-deprecated ways of exporting objects as listed below. </em> * * <p>There are eight ways to export remote objects: * @@ -90,10 +87,8 @@ * <p>The default value of the * {@code java.rmi.server.ignoreStubClasses} property is {@code false}. * - * <p>Statically generated stubs are typically pregenerated from the - * remote object's class using the {@code rmic} tool. A static stub is - * loaded and an instance of that stub class is constructed as described - * below. + * <p>Statically generated stubs are typically pregenerated from the remote object's class. + * A static stub is loaded and an instance of that stub class is constructed as described below. * * <ul> *
--- a/src/java.rmi/share/classes/java/rmi/server/package-info.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.rmi/share/classes/java/rmi/server/package-info.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * 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,31 +24,22 @@ */ /** - * Provides classes and interfaces for supporting the server - * side of RMI. A group of classes are used by the stubs and skeletons - * generated by the rmic stub compiler. Another group of classes - * implements the RMI Transport protocol and HTTP tunneling. - * - * <p><strong>Deprecated: HTTP Tunneling.</strong> <em>The HTTP tunneling - * mechanism has been deprecated. See {@link java.rmi.server.RMISocketFactory} for - * further information.</em> + * Provides classes and interfaces for supporting the server side of RMI. + * One group of classes are used by the static stubs and skeletons. + * Another group of classes implements the RMI Transport protocol. * * <p><strong>Deprecated: Skeletons and Static Stubs.</strong> * * <em>Skeletons and statically generated stubs are deprecated. This * includes the APIs in this package that require the use of skeletons - * or static stubs, the runtime support for them, and the use of the - * {@code rmic} stub compiler to generate them. Support for skeletons + * or static stubs and the runtime support for them. Support for skeletons * and static stubs may be removed in a future release of the * platform. Skeletons are unnecessary, as server-side method dispatching * is handled directly by the RMI runtime. Statically generated stubs are * unnecessary, as stubs are generated dynamically using {@link * java.lang.reflect.Proxy Proxy} objects. See {@link * java.rmi.server.UnicastRemoteObject UnicastRemoteObject} for - * information about dynamic stub generation. Generation of skeletons and - * static stubs was typically performed as part of an application's build - * process by calling the {@code rmic} tool. This is unnecessary, and - * calls to {@code rmic} can simply be omitted.</em> + * information about dynamic stub generation.</em> * * @since 1.1 */
--- a/src/java.xml/share/legal/xerces.md Tue Apr 07 18:30:32 2020 +0000 +++ b/src/java.xml/share/legal/xerces.md Fri Apr 10 17:10:22 2020 +0000 @@ -1,4 +1,4 @@ -## Apache Xerces v2.12.0 +## Apache Xerces v2.12.1 ### Apache Xerces Notice <pre> @@ -8,9 +8,11 @@ ========================================================================= Apache Xerces Java - Copyright 1999-2018 The Apache Software Foundation + Copyright 1999-2020 The Apache Software Foundation + This product includes software developed at The Apache Software Foundation (http://www.apache.org/). + Portions of this software were originally based on the following: - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. - software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java Fri Apr 10 17:10:22 2020 +0000 @@ -167,7 +167,6 @@ public boolean isPreview(Feature feature) { if (feature == Feature.PATTERN_MATCHING_IN_INSTANCEOF || feature == Feature.REIFIABLE_TYPES_INSTANCEOF || - feature == Feature.TEXT_BLOCKS || feature == Feature.RECORDS) return true; //Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing).
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Apr 10 17:10:22 2020 +0000 @@ -934,8 +934,8 @@ // These method calls must be chained to avoid memory leaks processAnnotations( enterTrees( - stopIfError(CompileState.PARSE, - initModules(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects)))) + stopIfError(CompileState.ENTER, + initModules(stopIfError(CompileState.ENTER, parseFiles(sourceFileObjects)))) ), classnames ); @@ -946,34 +946,36 @@ todo.retainFiles(inputFiles); } - switch (compilePolicy) { - case ATTR_ONLY: - attribute(todo); - break; + if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) { + switch (compilePolicy) { + case ATTR_ONLY: + attribute(todo); + break; - case CHECK_ONLY: - flow(attribute(todo)); - break; + case CHECK_ONLY: + flow(attribute(todo)); + break; - case SIMPLE: - generate(desugar(flow(attribute(todo)))); - break; + case SIMPLE: + generate(desugar(flow(attribute(todo)))); + break; - case BY_FILE: { - Queue<Queue<Env<AttrContext>>> q = todo.groupByFile(); - while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) { - generate(desugar(flow(attribute(q.remove())))); + case BY_FILE: { + Queue<Queue<Env<AttrContext>>> q = todo.groupByFile(); + while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) { + generate(desugar(flow(attribute(q.remove())))); + } } - } - break; + break; - case BY_TODO: - while (!todo.isEmpty()) - generate(desugar(flow(attribute(todo.remove())))); - break; + case BY_TODO: + while (!todo.isEmpty()) + generate(desugar(flow(attribute(todo.remove())))); + break; - default: - Assert.error("unknown compile policy"); + default: + Assert.error("unknown compile policy"); + } } } catch (Abort ex) { if (devVerbose) @@ -1179,7 +1181,7 @@ // Unless all the errors are resolve errors, the errors were parse errors // or other errors during enter which cannot be fixed by running // any annotation processors. - if (unrecoverableError()) { + if (processAnnotations) { deferredDiagnosticHandler.reportDeferredDiagnostics(); log.popDiagnosticHandler(deferredDiagnosticHandler); return ;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Fri Apr 10 17:10:22 2020 +0000 @@ -233,8 +233,8 @@ if (!multiline) { lexError(reader.bp, Errors.IllegalEscChar); } else { + checkSourceLevel(reader.bp, Feature.TEXT_BLOCKS); int start = reader.bp; - checkSourceLevel(reader.bp, Feature.TEXT_BLOCKS); if (reader.ch == '\r' && reader.peekChar() == '\n') { reader.nextChar(translateEscapesNow); } @@ -402,6 +402,17 @@ return count; } + /** Skip and process a line terminator. + */ + private void skipLineTerminator() { + int start = reader.bp; + if (isCRLF()) { + reader.scanChar(); + } + reader.scanChar(); + processLineTerminator(start, reader.bp); + } + /** Scan a string literal or text block. */ private void scanString(int pos) { @@ -425,26 +436,21 @@ checkSourceLevel(pos, Feature.TEXT_BLOCKS); isTextBlock = true; // Verify the open delimiter sequence. - boolean hasOpenEOLN = false; - while (reader.bp < reader.buflen && Character.isWhitespace(reader.ch)) { - hasOpenEOLN = isEOLN(); - if (hasOpenEOLN) { + while (reader.bp < reader.buflen) { + char ch = reader.ch; + if (ch != ' ' && ch != '\t' && ch != FF) { break; } reader.scanChar(); } - // Error if the open delimiter sequence not is """<Whitespace>*<LineTerminator>. - if (!hasOpenEOLN) { + if (isEOLN()) { + skipLineTerminator(); + } else { + // Error if the open delimiter sequence is not + // """<white space>*<LineTerminator>. lexError(reader.bp, Errors.IllegalTextBlockOpen); return; } - // Skip line terminator. - int start = reader.bp; - if (isCRLF()) { - reader.scanChar(); - } - reader.scanChar(); - processLineTerminator(start, reader.bp); break; } // While characters are available. @@ -466,13 +472,9 @@ if (openCount == 1) { break; } - // Add line terminator to string buffer. - int start = reader.bp; - if (isCRLF()) { - reader.scanChar(); - } - reader.putChar('\n', true); - processLineTerminator(start, reader.bp); + skipLineTerminator(); + // Add line terminator to string buffer. + reader.putChar('\n', false); // Record first line terminator for error recovery. if (firstEOLN == -1) { firstEOLN = reader.bp;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Apr 10 17:10:22 2020 +0000 @@ -27,6 +27,7 @@ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -78,8 +79,10 @@ import sun.jvm.hotspot.tools.PMap; import sun.jvm.hotspot.tools.PStack; import sun.jvm.hotspot.tools.StackTrace; +import sun.jvm.hotspot.tools.SysPropsDumper; import sun.jvm.hotspot.tools.jcore.ClassDump; import sun.jvm.hotspot.tools.jcore.ClassFilter; +import sun.jvm.hotspot.tools.jcore.ClassWriter; import sun.jvm.hotspot.types.CIntegerType; import sun.jvm.hotspot.types.Field; import sun.jvm.hotspot.types.Type; @@ -1703,6 +1706,76 @@ } } }, + new Command("dumpclass", "dumpclass {address | name} [directory]", false) { + public void doit(Tokens t) { + int tokenCount = t.countTokens(); + if (tokenCount != 1 && tokenCount != 2) { + usage(); + return; + } + + /* Find the InstanceKlass for specified class name or class address. */ + InstanceKlass ik = null; + String classname = t.nextToken(); + if (classname.startsWith("0x")) { + // treat it as address + VM vm = VM.getVM(); + Address addr = vm.getDebugger().parseAddress(classname); + Metadata metadata = Metadata.instantiateWrapperFor(addr.addOffsetTo(0)); + if (metadata instanceof InstanceKlass) { + ik = (InstanceKlass) metadata; + } else { + System.out.println("Specified address is not an InstanceKlass"); + return; + } + } else { + ik = SystemDictionaryHelper.findInstanceKlass(classname); + if (ik == null) { + System.out.println("class not found: " + classname); + return; + } + } + + /* Compute filename for class. */ + StringBuffer buf = new StringBuffer(); + if (tokenCount > 1) { + buf.append(t.nextToken()); + } else { + buf.append('.'); + } + buf.append(File.separatorChar); + buf.append(ik.getName().asString().replace('/', File.separatorChar)); + buf.append(".class"); + String fileName = buf.toString(); + File file = new File(fileName); + + /* Dump the class file. */ + try { + int index = fileName.lastIndexOf(File.separatorChar); + File dir = new File(fileName.substring(0, index)); + dir.mkdirs(); + try (FileOutputStream fos = new FileOutputStream(file)) { + ClassWriter cw = new ClassWriter(ik, fos); + cw.write(); + } + } catch (Exception e) { + err.println("Error: " + e); + if (verboseExceptions) { + e.printStackTrace(err); + } + } + } + }, + new Command("sysprops", "sysprops", false) { + public void doit(Tokens t) { + if (t.countTokens() != 0) { + usage(); + return; + } + SysPropsDumper sysProps = new SysPropsDumper(); + sysProps.run(); + } + }, new Command("dumpheap", "dumpheap [filename]", false) { public void doit(Tokens t) { if (t.countTokens() > 1) { @@ -1726,6 +1799,36 @@ } } }, + new Command("class", "class name", false) { + public void doit(Tokens t) { + if (t.countTokens() != 1) { + usage(); + return; + } + String classname = t.nextToken(); + InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass(classname); + if (ik == null) { + System.out.println("class not found: " + classname); + } else { + System.out.println(ik.getName().asString() + " @" + ik.getAddress()); + } + } + }, + new Command("classes", "classes", false) { + public void doit(Tokens t) { + if (t.countTokens() != 0) { + usage(); + return; + } + ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph(); + cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() { + public void visit(Klass k) { + System.out.println(k.getName().asString() + " @" + k.getAddress()); + } + } + ); + } + }, }; private boolean verboseExceptions = false;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Fri Apr 10 17:10:22 2020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * 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,6 +205,7 @@ InstanceKlass ik = (InstanceKlass)oop.getKlass(); OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;"); OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;"); + OopField nextField = (OopField)ik.findField("next", "Ljava/util/concurrent/ConcurrentHashMap$Node;"); try { p.setProperty((String)readObject(keyField.getValue(oop)), @@ -214,6 +215,11 @@ debugPrintStackTrace(ce); } } + // If this hashmap table Node is chained, then follow the chain to the next Node. + Oop chainedOop = nextField.getValue(oop); + if (chainedOop != null) { + setPropertiesEntry(p, chainedOop); + } } protected Object getHashtable(Instance oop) {
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java Fri Apr 10 17:10:22 2020 +0000 @@ -368,14 +368,28 @@ String signingIdentity = DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params); if (signingIdentity != null) { + prepareEntitlements(params); signAppBundle(params, root, signingIdentity, - BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params), null, null); + BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params), + getConfig_Entitlements(params)); } restoreKeychainList(params); } } - private String getLauncherName(Map<String, ? super Object> params) { + static File getConfig_Entitlements(Map<String, ? super Object> params) { + return new File(CONFIG_ROOT.fetchFrom(params), + getLauncherName(params) + ".entitlements"); + } + + static void prepareEntitlements(Map<String, ? super Object> params) + throws IOException { + createResource("entitlements.plist", params) + .setCategory(I18N.getString("resource.entitlements")) + .saveToFile(getConfig_Entitlements(params)); + } + + private static String getLauncherName(Map<String, ? super Object> params) { if (APP_NAME.fetchFrom(params) != null) { return APP_NAME.fetchFrom(params); } else { @@ -735,16 +749,15 @@ IOUtils.exec(pb); } - public static void signAppBundle( + static void signAppBundle( Map<String, ? super Object> params, Path appLocation, - String signingIdentity, String identifierPrefix, - String entitlementsFile, String inheritedEntitlements) + String signingIdentity, String identifierPrefix, File entitlements) throws IOException { AtomicReference<IOException> toThrow = new AtomicReference<>(); String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params); String keyChain = SIGNING_KEYCHAIN.fetchFrom(params); - // sign all dylibs and jars + // sign all dylibs and executables try (Stream<Path> stream = Files.walk(appLocation)) { stream.peek(path -> { // fix permissions try { @@ -758,48 +771,43 @@ } catch (IOException e) { Log.verbose(e); } - }).filter(p -> Files.isRegularFile(p) - && !(p.toString().contains("/Contents/MacOS/libjli.dylib") - || p.toString().endsWith(appExecutable) + }).filter(p -> Files.isRegularFile(p) && + (Files.isExecutable(p) || p.toString().endsWith(".dylib")) + && !(p.toString().endsWith(appExecutable) || p.toString().contains("/Contents/runtime") - || p.toString().contains("/Contents/Frameworks"))).forEach(p -> { - //noinspection ThrowableResultOfMethodCallIgnored + || p.toString().contains("/Contents/Frameworks")) + ).forEach(p -> { + // noinspection ThrowableResultOfMethodCallIgnored if (toThrow.get() != null) return; // If p is a symlink then skip the signing process. if (Files.isSymbolicLink(p)) { - if (VERBOSE.fetchFrom(params)) { - Log.verbose(MessageFormat.format(I18N.getString( - "message.ignoring.symlink"), p.toString())); - } + Log.verbose(MessageFormat.format(I18N.getString( + "message.ignoring.symlink"), p.toString())); + } else if (isFileSigned(p)) { + // executable or lib already signed + Log.verbose(MessageFormat.format(I18N.getString( + "message.already.signed"), p.toString())); } else { - if (p.toString().endsWith(LIBRARY_NAME)) { - if (isFileSigned(p)) { - return; - } - } - List<String> args = new ArrayList<>(); args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key + "--timestamp", + "--options", "runtime", + "-s", signingIdentity, "--prefix", identifierPrefix, - // use the identifier as a prefix "-vvvv")); - if (entitlementsFile != null && - (p.toString().endsWith(".jar") - || p.toString().endsWith(".dylib"))) { - args.add("--entitlements"); - args.add(entitlementsFile); // entitlements - } else if (inheritedEntitlements != null && - Files.isExecutable(p)) { - args.add("--entitlements"); - args.add(inheritedEntitlements); - // inherited entitlements for executable processes - } if (keyChain != null && !keyChain.isEmpty()) { args.add("--keychain"); args.add(keyChain); } + + if (Files.isExecutable(p)) { + if (entitlements != null) { + args.add("--entitlements"); + args.add(entitlements.toString()); + } + } + args.add(p.toString()); try { @@ -809,6 +817,7 @@ f.setWritable(true, true); ProcessBuilder pb = new ProcessBuilder(args); + IOUtils.exec(pb); Files.setPosixFilePermissions(p, oldPermissions); @@ -831,32 +840,22 @@ try { List<String> args = new ArrayList<>(); args.addAll(Arrays.asList("codesign", - "-f", + "--timestamp", + "--options", "runtime", + "--deep", + "--force", "-s", signingIdentity, // sign with this key "--prefix", identifierPrefix, // use the identifier as a prefix "-vvvv")); + if (keyChain != null && !keyChain.isEmpty()) { args.add("--keychain"); args.add(keyChain); } args.add(path.toString()); ProcessBuilder pb = new ProcessBuilder(args); - IOUtils.exec(pb); - args = new ArrayList<>(); - args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "--prefix", identifierPrefix, - // use the identifier as a prefix - "-vvvv")); - if (keyChain != null && !keyChain.isEmpty()) { - args.add("--keychain"); - args.add(keyChain); - } - args.add(path.toString() - + "/Contents/_CodeSignature/CodeResources"); - pb = new ProcessBuilder(args); IOUtils.exec(pb); } catch (IOException e) { toThrow.set(e); @@ -886,20 +885,28 @@ // sign the app itself List<String> args = new ArrayList<>(); args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "-vvvv")); // super verbose output - if (entitlementsFile != null) { - args.add("--entitlements"); - args.add(entitlementsFile); // entitlements - } + "--timestamp", + "--options", "runtime", + "--deep", + "--force", + "-s", signingIdentity, + "-vvvv")); + if (keyChain != null && !keyChain.isEmpty()) { args.add("--keychain"); args.add(keyChain); } + + if (entitlements != null) { + args.add("--entitlements"); + args.add(entitlements.toString()); + } + args.add(appLocation.toString()); ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()])); + IOUtils.exec(pb); }
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppStoreBundler.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppStoreBundler.java Fri Apr 10 17:10:22 2020 +0000 @@ -40,10 +40,6 @@ "jdk.incubator.jpackage.internal.resources.MacResources"); private static final String TEMPLATE_BUNDLE_ICON_HIDPI = "java.icns"; - private final static String DEFAULT_ENTITLEMENTS = - "MacAppStore.entitlements"; - private final static String DEFAULT_INHERIT_ENTITLEMENTS = - "MacAppStore_Inherit.entitlements"; public static final BundlerParamInfo<String> MAC_APP_STORE_APP_SIGNING_KEY = new StandardBundlerParam<>( @@ -94,13 +90,6 @@ }, (s, p) -> s); - public static final StandardBundlerParam<File> MAC_APP_STORE_ENTITLEMENTS = - new StandardBundlerParam<>( - Arguments.CLIOptions.MAC_APP_STORE_ENTITLEMENTS.getId(), - File.class, - params -> null, - (s, p) -> new File(s)); - public static final BundlerParamInfo<String> INSTALLER_SUFFIX = new StandardBundlerParam<> ( "mac.app-store.installerName.suffix", @@ -133,20 +122,15 @@ params.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), null); File appLocation = prepareAppBundle(params); - prepareEntitlements(params); - String signingIdentity = MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(params); String identifierPrefix = BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params); - String entitlementsFile = - getConfig_Entitlements(params).toString(); - String inheritEntitlements = - getConfig_Inherit_Entitlements(params).toString(); + MacAppImageBuilder.prepareEntitlements(params); MacAppImageBuilder.signAppBundle(params, appLocation.toPath(), signingIdentity, identifierPrefix, - entitlementsFile, inheritEntitlements); + MacAppImageBuilder.getConfig_Entitlements(params)); MacAppImageBuilder.restoreKeychainList(params); ProcessBuilder pb; @@ -188,31 +172,6 @@ } } - private File getConfig_Entitlements(Map<String, ? super Object> params) { - return new File(CONFIG_ROOT.fetchFrom(params), - APP_NAME.fetchFrom(params) + ".entitlements"); - } - - private File getConfig_Inherit_Entitlements( - Map<String, ? super Object> params) { - return new File(CONFIG_ROOT.fetchFrom(params), - APP_NAME.fetchFrom(params) + "_Inherit.entitlements"); - } - - private void prepareEntitlements(Map<String, ? super Object> params) - throws IOException { - createResource(DEFAULT_ENTITLEMENTS, params) - .setCategory( - I18N.getString("resource.mac-app-store-entitlements")) - .setExternal(MAC_APP_STORE_ENTITLEMENTS.fetchFrom(params)) - .saveToFile(getConfig_Entitlements(params)); - - createResource(DEFAULT_INHERIT_ENTITLEMENTS, params) - .setCategory(I18N.getString( - "resource.mac-app-store-inherit-entitlements")) - .saveToFile(getConfig_Entitlements(params)); - } - /////////////////////////////////////////////////////////////////////// // Implement Bundler ///////////////////////////////////////////////////////////////////////
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacAppStore.entitlements Tue Apr 07 18:30:32 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> - <dict> - <key>com.apple.security.app-sandbox</key> - <true/> - </dict> -</plist>
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacAppStore_Inherit.entitlements Tue Apr 07 18:30:32 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> - <dict> - <key>com.apple.security.app-sandbox</key> - <true/> - <key>com.apple.security.inherit</key> - <true/> - </dict> -</plist>
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties Fri Apr 10 17:10:22 2020 +0000 @@ -46,8 +46,7 @@ resource.bundle-config-file=Bundle config file resource.app-info-plist=Application Info.plist resource.runtime-info-plist=Java Runtime Info.plist -resource.mac-app-store-entitlements=Mac App Store Entitlements -resource.mac-app-store-inherit-entitlements=Mac App Store Inherit Entitlements +resource.entitlements=Mac Entitlements resource.dmg-setup-script=DMG setup script resource.license-setup=License setup resource.dmg-background=dmg background @@ -68,6 +67,7 @@ message.version-string-numbers-only=Version strings can consist of only numbers and up to two dots. message.creating-association-with-null-extension=Creating association with null extension. message.ignoring.symlink=Warning: codesign is skipping the symlink {0}. +message.already.signed=File already signed: {0}. message.keychain.error=Error: unable to get keychain list. message.building-bundle=Building Mac App Store Package for {0}. message.app-image-dir-does-not-exist=Specified application image directory {0}: {1} does not exists.
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties Fri Apr 10 17:10:22 2020 +0000 @@ -46,8 +46,7 @@ resource.bundle-config-file=\u30D0\u30F3\u30C9\u30EB\u69CB\u6210\u30D5\u30A1\u30A4\u30EB resource.app-info-plist=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306EInfo.plist resource.runtime-info-plist=Java\u30E9\u30F3\u30BF\u30A4\u30E0\u306EInfo.plist -resource.mac-app-store-entitlements=Mac App Store\u6A29\u9650 -resource.mac-app-store-inherit-entitlements=Mac App Store\u7D99\u627F\u6A29\u9650 +resource.entitlements=Mac Entitlements resource.dmg-setup-script=DMG\u8A2D\u5B9A\u30B9\u30AF\u30EA\u30D7\u30C8 resource.license-setup=\u30E9\u30A4\u30BB\u30F3\u30B9\u306E\u8A2D\u5B9A resource.dmg-background=dmg\u80CC\u666F @@ -68,6 +67,7 @@ message.version-string-numbers-only=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306F\u3001\u6570\u5B57\u30682\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u3067\u306E\u307F\u69CB\u6210\u3067\u304D\u307E\u3059\u3002 message.creating-association-with-null-extension=null\u62E1\u5F35\u5B50\u3068\u306E\u95A2\u9023\u4ED8\u3051\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059\u3002 message.ignoring.symlink=\u8B66\u544A: codesign\u304Csymlink {0}\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059 +message.already.signed=File already signed: {0}. message.keychain.error=\u30A8\u30E9\u30FC: \u30AD\u30FC\u30C1\u30A7\u30FC\u30F3\u30FB\u30EA\u30B9\u30C8\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3002 message.building-bundle={0}\u306EMac App Store\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059\u3002 message.app-image-dir-does-not-exist=\u6307\u5B9A\u3055\u308C\u305F\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A4\u30E1\u30FC\u30B8\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA {0}: {1}\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties Fri Apr 10 17:10:22 2020 +0000 @@ -46,8 +46,7 @@ resource.bundle-config-file=\u5305\u914D\u7F6E\u6587\u4EF6 resource.app-info-plist=\u5E94\u7528\u7A0B\u5E8F Info.plist resource.runtime-info-plist=Java \u8FD0\u884C\u65F6 Info.plist -resource.mac-app-store-entitlements=Mac App Store \u6743\u5229 -resource.mac-app-store-inherit-entitlements=Mac App Store \u7EE7\u627F\u6743\u5229 +resource.entitlements=Mac Entitlements resource.dmg-setup-script=DMG \u8BBE\u7F6E\u811A\u672C resource.license-setup=\u8BB8\u53EF\u8BC1\u8BBE\u7F6E resource.dmg-background=DMG \u80CC\u666F @@ -68,6 +67,7 @@ message.version-string-numbers-only=\u7248\u672C\u5B57\u7B26\u4E32\u53EA\u80FD\u5305\u542B\u6570\u5B57\u548C\u6700\u591A\u4E24\u4E2A\u70B9\u3002 message.creating-association-with-null-extension=\u6B63\u5728\u4F7F\u7528\u7A7A\u6269\u5C55\u540D\u521B\u5EFA\u5173\u8054\u3002 message.ignoring.symlink=\u8B66\u544A: codesign \u6B63\u5728\u8DF3\u8FC7\u7B26\u53F7\u94FE\u63A5 {0}\u3002 +message.already.signed=File already signed: {0}. message.keychain.error=\u9519\u8BEF\uFF1A\u65E0\u6CD5\u83B7\u53D6\u5BC6\u94A5\u94FE\u5217\u8868\u3002 message.building-bundle=\u6B63\u5728\u4E3A {0} \u6784\u5EFA Mac App Store \u7A0B\u5E8F\u5305\u3002 message.app-image-dir-does-not-exist=\u6307\u5B9A\u7684\u5E94\u7528\u7A0B\u5E8F\u6620\u50CF\u76EE\u5F55 {0}\uFF1A{1} \u4E0D\u5B58\u5728\u3002
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/entitlements.plist Fri Apr 10 17:10:22 2020 +0000 @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.cs.allow-jit</key> + <true/> + <key>com.apple.security.cs.allow-unsigned-executable-memory</key> + <true/> + <key>com.apple.security.cs.disable-library-validation</key> + <true/> + <key>com.apple.security.cs.allow-dyld-environment-variables</key> + <true/> + <key>com.apple.security.cs.debugger</key> + <true/> +</dict> +</plist>
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Arguments.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Arguments.java Fri Apr 10 17:10:22 2020 +0000 @@ -285,9 +285,6 @@ MAC_SIGNING_KEYCHAIN ("mac-signing-keychain", OptionCategories.PLATFORM_MAC), - MAC_APP_STORE_ENTITLEMENTS ("mac-app-store-entitlements", - OptionCategories.PLATFORM_MAC), - WIN_MENU_HINT ("win-menu", OptionCategories.PLATFORM_WIN, () -> { setOptionValue("win-menu", true); }),
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ValidOptions.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ValidOptions.java Fri Apr 10 17:10:22 2020 +0000 @@ -109,12 +109,9 @@ options.put(CLIOptions.MAC_SIGN.getId(), USE.ALL); options.put(CLIOptions.MAC_BUNDLE_NAME.getId(), USE.ALL); options.put(CLIOptions.MAC_BUNDLE_IDENTIFIER.getId(), USE.ALL); - options.put(CLIOptions.MAC_BUNDLE_SIGNING_PREFIX.getId(), - USE.ALL); + options.put(CLIOptions.MAC_BUNDLE_SIGNING_PREFIX.getId(), USE.ALL); options.put(CLIOptions.MAC_SIGNING_KEY_NAME.getId(), USE.ALL); options.put(CLIOptions.MAC_SIGNING_KEYCHAIN.getId(), USE.ALL); - options.put(CLIOptions.MAC_APP_STORE_ENTITLEMENTS.getId(), - USE.ALL); } if (Platform.getPlatform() == Platform.LINUX) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -90,7 +90,7 @@ deprecatedLinkContent.add("."); deprecatedLinkContent.add(member.getSimpleName()); } - String signature = utils.flatSignature((ExecutableElement) member); + String signature = utils.flatSignature((ExecutableElement) member, typeElement); if (signature.length() > 2) { deprecatedLinkContent.add(Entity.ZERO_WIDTH_SPACE); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.Writer; -import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -35,11 +34,11 @@ import java.util.stream.Stream; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.SimpleElementVisitor14; import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem.Category; @@ -55,6 +54,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder; +import jdk.javadoc.internal.doclets.toolkit.util.IndexItem; /** * Generate Index for all the Member Names with Indexing in @@ -96,80 +96,17 @@ this.navBar = new Navigation(null, configuration, PageMode.INDEX, path); Stream<SearchIndexItem> items = searchItems.itemsOfCategories(Category.INDEX, Category.SYSTEM_PROPERTY) - .sorted(utils.makeGenericSearchIndexComparator()); + .sorted(comparators.makeGenericSearchIndexComparator()); this.tagSearchIndexMap = buildSearchTagIndex(items); } - /** - * Add the member information for the unicode character along with the - * list of the members. - * - * @param uc Unicode for which member list information to be generated - * @param memberlist List of members for the unicode character - * @param contentTree the content tree to which the information will be added - */ - protected void addContents(Character uc, Collection<? extends Element> memberlist, - Content contentTree) { - addHeading(uc, contentTree); - // Display the list only if there are elements to be displayed. - if (!memberlist.isEmpty()) { - HtmlTree dl = HtmlTree.DL(HtmlStyle.index); - for (Element element : memberlist) { - addDescription(dl, element); - } - contentTree.add(dl); - } - } - - protected void addSearchContents(Character uc, List<SearchIndexItem> searchList, + protected void addContents(Character uc, List<IndexItem> memberlist, Content contentTree) { addHeading(uc, contentTree); - // Display the list only if there are elements to be displayed. - if (!searchList.isEmpty()) { - HtmlTree dl = HtmlTree.DL(HtmlStyle.index); - for (SearchIndexItem sii : searchList) { - addDescription(sii, dl); - } - contentTree.add(dl); - } - } - protected void addContents(Character uc, List<? extends Element> memberlist, - List<SearchIndexItem> searchList, Content contentTree) { - addHeading(uc, contentTree); - int memberListSize = memberlist.size(); - int searchListSize = searchList.size(); - int i = 0; - int j = 0; HtmlTree dl = HtmlTree.DL(HtmlStyle.index); - while (i < memberListSize && j < searchListSize) { - Element elem = memberlist.get(i); - String name = (utils.isModule(elem)) - ? utils.getFullyQualifiedName(elem) : utils.getSimpleName(elem); - if (name.compareTo(searchList.get(j).getLabel()) < 0) { - addDescription(dl, memberlist.get(i)); - i++; - } else if (name.compareTo(searchList.get(j).getLabel()) > 0) { - addDescription(searchList.get(j), dl); - j++; - } else { - addDescription(dl, memberlist.get(i)); - addDescription(searchList.get(j), dl); - j++; - i++; - } - } - if (i >= memberListSize) { - while (j < searchListSize) { - addDescription(searchList.get(j), dl); - j++; - } - } - if (j >= searchListSize) { - while (i < memberListSize) { - addDescription(dl, memberlist.get(i)); - i++; - } + for (IndexItem indexItem : memberlist) { + addDescription(indexItem, dl); } contentTree.add(dl); } @@ -183,109 +120,78 @@ contentTree.add(heading); } - @SuppressWarnings("preview") - protected void addDescription(Content dl, Element element) { - SearchIndexItem si = new SearchIndexItem(); - new SimpleElementVisitor14<Void, Void>() { - - @Override - public Void visitModule(ModuleElement e, Void p) { - if (configuration.showModules) { - addDescription(e, dl, si); - searchItems.add(si); - } - return null; - } - - @Override - public Void visitPackage(PackageElement e, Void p) { - addDescription(e, dl, si); - searchItems.add(si); - return null; - } - - @Override - public Void visitType(TypeElement e, Void p) { - addDescription(e, dl, si); - searchItems.add(si); - return null; - } - - @Override - protected Void defaultAction(Element e, Void p) { - addDescription(e, dl, si); - searchItems.add(si); - return null; - } - - }.visit(element); + protected void addDescription(IndexItem indexItem, Content dl) { + SearchIndexItem si = indexItem.getSearchTag(); + if (si != null) { + addDescription(si, dl); + } else { + si = new SearchIndexItem(); + si.setLabel(indexItem.getLabel()); + addElementDescription(indexItem, dl, si); + searchItems.add(si); + } } /** - * Add one line summary comment for the module. + * Add one line summary comment for the element. * - * @param mdle the module to be documented + * @param indexItem the element to be documented * @param dlTree the content tree to which the description will be added * @param si the search index item */ - protected void addDescription(ModuleElement mdle, Content dlTree, SearchIndexItem si) { - String moduleName = utils.getFullyQualifiedName(mdle); - Content link = getModuleLink(mdle, new StringContent(moduleName)); - si.setLabel(moduleName); - si.setCategory(Category.MODULES); - Content dt = HtmlTree.DT(link); - dt.add(" - "); - dt.add(contents.module_); - dt.add(" " + moduleName); + protected void addElementDescription(IndexItem indexItem, Content dlTree, SearchIndexItem si) { + Content dt; + Element element = indexItem.getElement(); + String label = indexItem.getLabel(); + switch (element.getKind()) { + case MODULE: + dt = HtmlTree.DT(getModuleLink((ModuleElement)element, new StringContent(label))); + si.setCategory(Category.MODULES); + dt.add(" - ").add(contents.module_).add(" " + label); + break; + case PACKAGE: + dt = HtmlTree.DT(getPackageLink((PackageElement)element, new StringContent(label))); + if (configuration.showModules) { + si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(element))); + } + si.setCategory(Category.PACKAGES); + dt.add(" - ").add(contents.package_).add(" " + label); + break; + case CLASS: + case ENUM: + case ANNOTATION_TYPE: + case INTERFACE: + dt = HtmlTree.DT(getLink(new LinkInfoImpl(configuration, + LinkInfoImpl.Kind.INDEX, (TypeElement)element).strong(true))); + si.setContainingPackage(utils.getPackageName(utils.containingPackage(element))); + si.setCategory(Category.TYPES); + dt.add(" - "); + addClassInfo((TypeElement)element, dt); + break; + default: + TypeElement containingType = indexItem.getTypeElement(); + dt = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.memberNameLink, + getDocLink(LinkInfoImpl.Kind.INDEX, containingType, element, new StringContent(label)))); + si.setContainingPackage(utils.getPackageName(utils.containingPackage(element))); + si.setContainingClass(utils.getSimpleName(containingType)); + if (utils.isExecutableElement(element)) { + String url = HtmlTree.encodeURL(links.getName(getAnchor((ExecutableElement)element))); + if (!label.equals(url)) { + si.setUrl(url); + } + } + si.setCategory(Category.MEMBERS); + dt.add(" - "); + addMemberDesc(element, containingType, dt); + break; + } dlTree.add(dt); Content dd = new HtmlTree(TagName.DD); - addSummaryComment(mdle, dd); - dlTree.add(dd); - } - - /** - * Add one line summary comment for the package. - * - * @param pkg the package to be documented - * @param dlTree the content tree to which the description will be added - * @param si the search index item to be updated - */ - protected void addDescription(PackageElement pkg, Content dlTree, SearchIndexItem si) { - Content link = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))); - if (configuration.showModules) { - si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(pkg))); + if (element.getKind() == ElementKind.MODULE || element.getKind() == ElementKind.PACKAGE) { + addSummaryComment(element, dd); + } else { + addComment(element, dd); } - si.setLabel(utils.getPackageName(pkg)); - si.setCategory(Category.PACKAGES); - Content dt = HtmlTree.DT(link); - dt.add(" - "); - dt.add(contents.package_); - dt.add(" " + utils.getPackageName(pkg)); - dlTree.add(dt); - Content dd = new HtmlTree(TagName.DD); - addSummaryComment(pkg, dd); - dlTree.add(dd); - } - - /** - * Add one line summary comment for the class. - * - * @param typeElement the class being documented - * @param dlTree the content tree to which the description will be added - * @param si the search index item to be updated - */ - protected void addDescription(TypeElement typeElement, Content dlTree, SearchIndexItem si) { - Content link = getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.INDEX, typeElement).strong(true)); - si.setContainingPackage(utils.getPackageName(utils.containingPackage(typeElement))); - si.setLabel(utils.getSimpleName(typeElement)); - si.setCategory(Category.TYPES); - Content dt = HtmlTree.DT(link); - dt.add(" - "); - addClassInfo(typeElement, dt); - dlTree.add(dt); - Content dd = new HtmlTree(TagName.DD); - addComment(typeElement, dd); dlTree.add(dd); } @@ -304,41 +210,6 @@ )); } - /** - * Add description for Class, Field, Method or Constructor. - * - * @param member the member of the Class Kind - * @param dlTree the content tree to which the description will be added - * @param si search index item - */ - protected void addDescription(Element member, Content dlTree, SearchIndexItem si) { - - si.setContainingPackage(utils.getPackageName(utils.containingPackage(member))); - si.setContainingClass(utils.getSimpleName(utils.getEnclosingTypeElement(member))); - String name = utils.getSimpleName(member); - if (utils.isExecutableElement(member)) { - ExecutableElement ee = (ExecutableElement)member; - name = name + utils.flatSignature(ee); - si.setLabel(name); - String url = HtmlTree.encodeURL(links.getName(getAnchor(ee))); - if (!name.equals(url)) { - si.setUrl(url); - } - } else { - si.setLabel(name); - } - si.setCategory(Category.MEMBERS); - Content span = HtmlTree.SPAN(HtmlStyle.memberNameLink, - getDocLink(LinkInfoImpl.Kind.INDEX, member, name)); - Content dt = HtmlTree.DT(span); - dt.add(" - "); - addMemberDesc(member, dt); - dlTree.add(dt); - Content dd = new HtmlTree(TagName.DD); - addComment(member, dd); - dlTree.add(dd); - } - protected void addDescription(SearchIndexItem sii, Content dlTree) { String siiPath = pathToRoot.isEmpty() ? "" : pathToRoot.getPath() + "/"; siiPath += sii.getUrl(); @@ -394,12 +265,12 @@ * Add description about the Static Variable/Method/Constructor for a * member. * - * @param member MemberDoc for the member within the Class Kind + * @param member element for the member + * @param enclosing the enclosing type element * @param contentTree the content tree to which the member description will be added */ - protected void addMemberDesc(Element member, Content contentTree) { - TypeElement containing = utils.getEnclosingTypeElement(member); - String classdesc = utils.getTypeElementName(containing, true) + " "; + protected void addMemberDesc(Element member, TypeElement enclosing, Content contentTree) { + String classdesc = utils.getTypeElementName(enclosing, true) + " "; if (utils.isField(member)) { Content resource = contents.getContent(utils.isStatic(member) ? "doclet.Static_variable_in" @@ -414,7 +285,7 @@ : "doclet.Method_in", classdesc); contentTree.add(resource); } - addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, containing, + addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, enclosing, false, contentTree); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -135,7 +135,7 @@ TypeElement typeElement, Content contentTree) { - SortedSet<TypeElement> interfaces = new TreeSet<>(utils.makeGeneralPurposeComparator()); + SortedSet<TypeElement> interfaces = new TreeSet<>(comparators.makeGeneralPurposeComparator()); typeElement.getInterfaces().forEach(t -> interfaces.add(utils.asTypeElement(t))); if (interfaces.size() > (utils.isInterface(typeElement) ? 1 : 0)) { boolean isFirst = true;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -22,12 +22,12 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package jdk.javadoc.internal.doclets.formats.html; import java.util.ArrayList; import java.util.List; -import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import com.sun.source.doctree.DocTree; @@ -43,6 +43,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder; +import jdk.javadoc.internal.doclets.toolkit.util.IndexItem; /** * Generate the file with list of all the classes in this run. @@ -132,9 +133,9 @@ .addTab(resources.annotationTypeSummary, utils::isAnnotationType) .setTabScript(i -> "show(" + i + ");"); for (Character unicode : indexBuilder.keys()) { - for (Element element : indexBuilder.getMemberList(unicode)) { - TypeElement typeElement = (TypeElement) element; - if (!utils.isCoreClass(typeElement)) { + for (IndexItem indexItem : indexBuilder.getMemberList(unicode)) { + TypeElement typeElement = (TypeElement) indexItem.getElement(); + if (typeElement == null || !utils.isCoreClass(typeElement)) { continue; } addTableRow(table, typeElement);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -109,7 +109,7 @@ new StringContent(simpleName)); annotationDocTree.add(heading); return HtmlTree.SECTION(HtmlStyle.detail, annotationDocTree) - .setId(simpleName + utils.signature((ExecutableElement) member)); + .setId(simpleName + utils.signature((ExecutableElement) member, typeElement)); } @Override
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -107,11 +107,11 @@ super(configuration, filename); this.typeElement = typeElement; if (mapper.classToPackageAnnotations.containsKey(typeElement)) { - pkgToPackageAnnotations = new TreeSet<>(utils.makeClassUseComparator()); + pkgToPackageAnnotations = new TreeSet<>(comparators.makeClassUseComparator()); pkgToPackageAnnotations.addAll(mapper.classToPackageAnnotations.get(typeElement)); } configuration.currentTypeElement = typeElement; - this.pkgSet = new TreeSet<>(utils.makePackageComparator()); + this.pkgSet = new TreeSet<>(comparators.makePackageComparator()); this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam); this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations); this.pkgToMethodTypeParameter = pkgDivide(mapper.classToMethodTypeParam); @@ -181,7 +181,7 @@ Map<PackageElement, List<Element>> map = new HashMap<>(); List<? extends Element> elements = (List<? extends Element>) classMap.get(typeElement); if (elements != null) { - Collections.sort(elements, utils.makeClassUseComparator()); + Collections.sort(elements, comparators.makeClassUseComparator()); for (Element e : elements) { PackageElement pkg = utils.containingPackage(e); pkgSet.add(pkg);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -409,7 +409,7 @@ @Override public void addImplementedInterfacesInfo(Content classInfoTree) { - SortedSet<TypeMirror> interfaces = new TreeSet<>(utils.makeTypeMirrorClassUseComparator()); + SortedSet<TypeMirror> interfaces = new TreeSet<>(comparators.makeTypeMirrorClassUseComparator()); interfaces.addAll(utils.getAllInterfaces(typeElement)); if (utils.isClass(typeElement) && !interfaces.isEmpty()) { HtmlTree dl = HtmlTree.DL(HtmlStyle.notes); @@ -422,7 +422,7 @@ @Override public void addSuperInterfacesInfo(Content classInfoTree) { SortedSet<TypeMirror> interfaces = - new TreeSet<>(utils.makeTypeMirrorIndexUseComparator()); + new TreeSet<>(comparators.makeTypeMirrorIndexUseComparator()); interfaces.addAll(utils.getAllInterfaces(typeElement)); if (utils.isInterface(typeElement) && !interfaces.isEmpty()) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -153,16 +153,13 @@ @Override public Content getConstructorDetails(Content constructorDetailsTreeHeader, Content constructorDetailsTree) { - Content constructorDetails = new ContentBuilder(constructorDetailsTreeHeader, constructorDetailsTree); - return getMemberTree(HtmlTree.SECTION(HtmlStyle.constructorDetails, constructorDetails) - .setId(SectionName.CONSTRUCTOR_DETAIL.getName())); + return writer.getDetailsListItem( + HtmlTree.SECTION(HtmlStyle.constructorDetails) + .setId(SectionName.CONSTRUCTOR_DETAIL.getName()) + .add(constructorDetailsTreeHeader) + .add(constructorDetailsTree)); } - /** - * Let the writer know whether a non public constructor was found. - * - * @param foundNonPubConstructor true if we found a non public constructor. - */ @Override public void setFoundNonPubConstructor(boolean foundNonPubConstructor) { this.foundNonPubConstructor = foundNonPubConstructor;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -121,10 +121,11 @@ @Override public Content getEnumConstantsDetails(Content enumConstantsDetailsTreeHeader, Content enumConstantsDetailsTree) { - Content enumConstantsDetails = - new ContentBuilder(enumConstantsDetailsTreeHeader, enumConstantsDetailsTree); - return getMemberTree(HtmlTree.SECTION(HtmlStyle.constantDetails, enumConstantsDetails) - .setId(SectionName.ENUM_CONSTANT_DETAIL.getName())); + return writer.getDetailsListItem( + HtmlTree.SECTION(HtmlStyle.constantDetails) + .setId(SectionName.ENUM_CONSTANT_DETAIL.getName()) + .add(enumConstantsDetailsTreeHeader) + .add(enumConstantsDetailsTree)); } @Override
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -122,9 +122,11 @@ @Override public Content getFieldDetails(Content fieldDetailsTreeHeader, Content fieldDetailsTree) { - Content fieldDetails = new ContentBuilder(fieldDetailsTreeHeader, fieldDetailsTree); - return getMemberTree(HtmlTree.SECTION(HtmlStyle.fieldDetails, fieldDetails) - .setId(SectionName.FIELD_DETAIL.getName())); + return writer.getDetailsListItem( + HtmlTree.SECTION(HtmlStyle.fieldDetails) + .setId(SectionName.FIELD_DETAIL.getName()) + .add(fieldDetailsTreeHeader) + .add(fieldDetailsTree)); } @Override
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -77,7 +77,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.FixedStringContent; import jdk.javadoc.internal.doclets.formats.html.markup.Head; -import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; @@ -94,6 +93,7 @@ import jdk.javadoc.internal.doclets.toolkit.Resources; import jdk.javadoc.internal.doclets.toolkit.taglets.DocRootTaglet; import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter; +import jdk.javadoc.internal.doclets.toolkit.util.Comparators; import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; import jdk.javadoc.internal.doclets.toolkit.util.DocFile; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; @@ -168,6 +168,8 @@ protected final DocPaths docPaths; + protected final Comparators comparators; + /** * To check whether annotation heading is printed or not. */ @@ -218,6 +220,7 @@ this.resources = configuration.docResources; this.links = new Links(path); this.utils = configuration.utils; + this.comparators = utils.comparators; this.path = path; this.pathToRoot = path.parent().invert(); this.filename = path.basename(); @@ -990,7 +993,7 @@ return executableElement.getSimpleName().toString(); } String member = anchorName(executableElement); - String erasedSignature = utils.makeSignature(executableElement, true, true); + String erasedSignature = utils.makeSignature(executableElement, null, true, true); return member + erasedSignature; } @@ -1119,7 +1122,7 @@ } if (utils.isExecutableElement(refMem)) { if (refMemName.indexOf('(') < 0) { - refMemName += utils.makeSignature((ExecutableElement)refMem, true); + refMemName += utils.makeSignature((ExecutableElement) refMem, null, true); } if (overriddenMethod != null) { // The method to actually link.
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -314,7 +314,7 @@ VisibleMemberTable vmt = writer.configuration .getVisibleMemberTable(utils.getEnclosingTypeElement(method)); SortedSet<ExecutableElement> implementedMethods = - new TreeSet<>(utils.makeOverrideUseComparator()); + new TreeSet<>(utils.comparators.makeOverrideUseComparator()); implementedMethods.addAll(vmt.getImplementedMethods(method)); for (ExecutableElement implementedMeth : implementedMethods) { TypeMirror intfac = vmt.getImplementedMethodHolder(method, implementedMeth);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -84,13 +84,13 @@ * Map of module elements and modifiers required by this module. */ private final Map<ModuleElement, Content> requires - = new TreeMap<>(utils.makeModuleComparator()); + = new TreeMap<>(comparators.makeModuleComparator()); /** * Map of indirect modules and modifiers, transitive closure, required by this module. */ private final Map<ModuleElement, Content> indirectModules - = new TreeMap<>(utils.makeModuleComparator()); + = new TreeMap<>(comparators.makeModuleComparator()); /** * Details about a package in a module. @@ -120,44 +120,44 @@ /** * Map of packages of this module, and details of whether they are exported or opened. */ - private final Map<PackageElement, PackageEntry> packages = new TreeMap<>(utils.makePackageComparator()); + private final Map<PackageElement, PackageEntry> packages = new TreeMap<>(utils.comparators.makePackageComparator()); /** * Map of indirect modules (transitive closure) and their exported packages. */ private final Map<ModuleElement, SortedSet<PackageElement>> indirectPackages - = new TreeMap<>(utils.makeModuleComparator()); + = new TreeMap<>(comparators.makeModuleComparator()); /** * Map of indirect modules (transitive closure) and their open packages. */ private final Map<ModuleElement, SortedSet<PackageElement>> indirectOpenPackages - = new TreeMap<>(utils.makeModuleComparator()); + = new TreeMap<>(comparators.makeModuleComparator()); /** * Set of services used by the module. */ private final SortedSet<TypeElement> uses - = new TreeSet<>(utils.makeAllClassesComparator()); + = new TreeSet<>(comparators.makeAllClassesComparator()); /** * Map of services used by the module and specified using @uses javadoc tag, and description. */ private final Map<TypeElement, Content> usesTrees - = new TreeMap<>(utils.makeAllClassesComparator()); + = new TreeMap<>(comparators.makeAllClassesComparator()); /** * Map of services provided by this module, and set of its implementations. */ private final Map<TypeElement, SortedSet<TypeElement>> provides - = new TreeMap<>(utils.makeAllClassesComparator()); + = new TreeMap<>(comparators.makeAllClassesComparator()); /** * Map of services provided by the module and specified using @provides javadoc tag, and * description. */ private final Map<TypeElement, Content> providesTrees - = new TreeMap<>(utils.makeAllClassesComparator()); + = new TreeMap<>(comparators.makeAllClassesComparator()); private final Navigation navBar; @@ -288,7 +288,7 @@ // Include package if in details mode, or exported to all (i.e. targetModules == null) if (moduleMode == ModuleMode.ALL || targetMdles == null) { PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry()); - SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator()); + SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.comparators.makeModuleComparator()); if (targetMdles != null) { mdleList.addAll(targetMdles); } @@ -306,7 +306,7 @@ // Include package if in details mode, or opened to all (i.e. targetModules == null) if (moduleMode == ModuleMode.ALL || targetMdles == null) { PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry()); - SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator()); + SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.comparators.makeModuleComparator()); if (targetMdles != null) { mdleList.addAll(targetMdles); } @@ -318,7 +318,7 @@ // Get all the exported and opened packages, for the transitive closure of the module, to be displayed in // the indirect packages tables. dependentModules.forEach((module, mod) -> { - SortedSet<PackageElement> exportedPackages = new TreeSet<>(utils.makePackageComparator()); + SortedSet<PackageElement> exportedPackages = new TreeSet<>(utils.comparators.makePackageComparator()); ElementFilter.exportsIn(module.getDirectives()).forEach(directive -> { PackageElement pkg = directive.getPackage(); if (shouldDocument(pkg)) { @@ -333,7 +333,7 @@ if (!exportedPackages.isEmpty()) { indirectPackages.put(module, exportedPackages); } - SortedSet<PackageElement> openPackages = new TreeSet<>(utils.makePackageComparator()); + SortedSet<PackageElement> openPackages = new TreeSet<>(utils.comparators.makePackageComparator()); if (module.isOpen()) { openPackages.addAll(utils.getModulePackageMap().getOrDefault(module, Collections.emptySet())); } else { @@ -365,7 +365,7 @@ TypeElement u = directive.getService(); if (shouldDocument(u)) { List<? extends TypeElement> implList = directive.getImplementations(); - SortedSet<TypeElement> implSet = new TreeSet<>(utils.makeAllClassesComparator()); + SortedSet<TypeElement> implSet = new TreeSet<>(utils.comparators.makeAllClassesComparator()); implSet.addAll(implList); provides.put(u, implSet); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -88,7 +88,7 @@ Set<TypeElement> usedClasses = usingPackageToUsedClasses .get(utils.getPackageName(usingPackage)); if (usedClasses == null) { - usedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator()); + usedClasses = new TreeSet<>(comparators.makeGeneralPurposeComparator()); usingPackageToUsedClasses.put(utils.getPackageName(usingPackage), usedClasses); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -134,9 +134,11 @@ @Override public Content getPropertyDetails(Content propertyDetailsTreeHeader, Content propertyDetailsTree) { - Content propertyDetails = new ContentBuilder(propertyDetailsTreeHeader, propertyDetailsTree); - return getMemberTree(HtmlTree.SECTION(HtmlStyle.propertyDetails, propertyDetails) - .setId(SectionName.PROPERTY_DETAIL.getName())); + return writer.getDetailsListItem( + HtmlTree.SECTION(HtmlStyle.propertyDetails) + .setId(SectionName.PROPERTY_DETAIL.getName()) + .add(propertyDetailsTreeHeader) + .add(propertyDetailsTree)); } @Override
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItems.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItems.java Fri Apr 10 17:10:22 2020 +0000 @@ -69,9 +69,9 @@ private Set<SearchIndexItem> newSetForCategory(Category category) { final Comparator<SearchIndexItem> cmp; if (category == Category.TYPES) { - cmp = utils.makeTypeSearchIndexComparator(); + cmp = utils.comparators.makeTypeSearchIndexComparator(); } else { - cmp = utils.makeGenericSearchIndexComparator(); + cmp = utils.comparators.makeGenericSearchIndexComparator(); } return new TreeSet<>(cmp); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -105,14 +105,10 @@ elements.addAll(tagSearchIndexMap.keySet()); addLinksForIndexes(mainContent); for (Character unicode : elements) { - if (tagSearchIndexMap.get(unicode) == null) { - addContents(unicode, indexBuilder.getMemberList(unicode), mainContent); - } else if (indexBuilder.getMemberList(unicode) == null) { - addSearchContents(unicode, tagSearchIndexMap.get(unicode), mainContent); - } else { - addContents(unicode, indexBuilder.getMemberList(unicode), - tagSearchIndexMap.get(unicode), mainContent); + if (tagSearchIndexMap.get(unicode) != null) { + indexBuilder.addSearchTags(unicode, tagSearchIndexMap.get(unicode)); } + addContents(unicode, indexBuilder.getMemberList(unicode), mainContent); } addLinksForIndexes(mainContent); HtmlTree footer = HtmlTree.FOOTER();
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -135,14 +135,10 @@ contents.getContent("doclet.Index")))); Content mainContent = new ContentBuilder(); addLinksForIndexes(mainContent); - if (tagSearchIndexMap.get(unicode) == null) { - addContents(unicode, indexBuilder.getMemberList(unicode), mainContent); - } else if (indexBuilder.getMemberList(unicode) == null) { - addSearchContents(unicode, tagSearchIndexMap.get(unicode), mainContent); - } else { - addContents(unicode, indexBuilder.getMemberList(unicode), - tagSearchIndexMap.get(unicode), mainContent); + if (tagSearchIndexMap.get(unicode) != null) { + indexBuilder.addSearchTags(unicode, tagSearchIndexMap.get(unicode)); } + addContents(unicode, indexBuilder.getMemberList(unicode), mainContent); addLinksForIndexes(mainContent); main.add(mainContent); HtmlTree footer = HtmlTree.FOOTER();
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -213,6 +213,25 @@ } /** + * Returns a list to be used for the list of details for members of a given kind. + * + * @return a list to be used for the list of details for members of a given kind + */ + public Content getDetailsList() { + return new HtmlTree(TagName.UL).setStyle(HtmlStyle.detailsList); + } + + /** + * Returns an item for the list of details for members of a given kind. + * + * @param content content for the item + * @return an item for the list of details for members of a given kind + */ + public Content getDetailsListItem(Content content) { + return HtmlTree.LI(content); + } + + /** * Returns a list to be used for the list of members of a given kind. * * @return a list to be used for the list of members of a given kind @@ -224,11 +243,11 @@ /** * Returns an item for the list of elements of a given kind * - * @param contentTree the tree used to generate the complete member tree + * @param content content for the item * @return an item for the list of elements of a given kind */ - public Content getMemberListItem(Content contentTree) { - return HtmlTree.LI(contentTree); + public Content getMemberListItem(Content content) { + return HtmlTree.LI(content); } public Content getMemberInheritedTree() {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -432,7 +432,8 @@ @Override public Void visitExecutable(ExecutableElement e, Void p) { si.setHolder(utils.getFullyQualifiedName(utils.getEnclosingTypeElement(e)) - + "." + utils.getSimpleName(e) + utils.flatSignature(e)); + + "." + utils.getSimpleName(e) + + utils.flatSignature(e, htmlWriter.getCurrentPageElement())); return null; }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactoryImpl.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactoryImpl.java Fri Apr 10 17:10:22 2020 +0000 @@ -97,29 +97,29 @@ @Override public EnumConstantWriterImpl getEnumConstantWriter(ClassWriter classWriter) { - return new EnumConstantWriterImpl((SubWriterHolderWriter) classWriter, + return new EnumConstantWriterImpl((ClassWriterImpl) classWriter, classWriter.getTypeElement()); } @Override public FieldWriterImpl getFieldWriter(ClassWriter classWriter) { - return new FieldWriterImpl((SubWriterHolderWriter) classWriter, classWriter.getTypeElement()); + return new FieldWriterImpl((ClassWriterImpl) classWriter, classWriter.getTypeElement()); } @Override public PropertyWriterImpl getPropertyWriter(ClassWriter classWriter) { - return new PropertyWriterImpl((SubWriterHolderWriter) classWriter, + return new PropertyWriterImpl((ClassWriterImpl) classWriter, classWriter.getTypeElement()); } @Override public MethodWriterImpl getMethodWriter(ClassWriter classWriter) { - return new MethodWriterImpl((SubWriterHolderWriter) classWriter, classWriter.getTypeElement()); + return new MethodWriterImpl((ClassWriterImpl) classWriter, classWriter.getTypeElement()); } @Override public ConstructorWriterImpl getConstructorWriter(ClassWriter classWriter) { - return new ConstructorWriterImpl((SubWriterHolderWriter) classWriter, + return new ConstructorWriterImpl((ClassWriterImpl) classWriter, classWriter.getTypeElement()); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java Fri Apr 10 17:10:22 2020 +0000 @@ -68,6 +68,7 @@ deprecationComment, descfrmTypeLabel, details, + detailsList, detail, externalLink, fieldDetails,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Fri Apr 10 17:10:22 2020 +0000 @@ -265,7 +265,7 @@ protected void generateClassFiles(DocletEnvironment docEnv, ClassTree classtree) throws DocletException { generateClassFiles(classtree); - SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator()); + SortedSet<PackageElement> packages = new TreeSet<>(utils.comparators.makePackageComparator()); packages.addAll(configuration.getSpecifiedPackageElements()); configuration.modulePackages.values().stream().forEach(packages::addAll); for (PackageElement pkg : packages) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Fri Apr 10 17:10:22 2020 +0000 @@ -47,6 +47,7 @@ import jdk.javadoc.internal.doclets.formats.html.HtmlDoclet; import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory; import jdk.javadoc.internal.doclets.toolkit.taglets.TagletManager; +import jdk.javadoc.internal.doclets.toolkit.util.Comparators; import jdk.javadoc.internal.doclets.toolkit.util.DocFile; import jdk.javadoc.internal.doclets.toolkit.util.DocFileFactory; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; @@ -308,16 +309,17 @@ } private void initModules() { + Comparators comparators = utils.comparators; // Build the modules structure used by the doclet - modules = new TreeSet<>(utils.makeModuleComparator()); + modules = new TreeSet<>(comparators.makeModuleComparator()); modules.addAll(getSpecifiedModuleElements()); - modulePackages = new TreeMap<>(utils.makeModuleComparator()); + modulePackages = new TreeMap<>(comparators.makeModuleComparator()); for (PackageElement p : packages) { ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set<PackageElement> s = modulePackages - .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator())); + .computeIfAbsent(mdle, m -> new TreeSet<>(comparators.makePackageComparator())); s.add(p); } } @@ -326,7 +328,7 @@ ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set<PackageElement> s = modulePackages - .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator())); + .computeIfAbsent(mdle, m -> new TreeSet<>(comparators.makePackageComparator())); s.add(p); } } @@ -342,7 +344,7 @@ } private void initPackages() { - packages = new TreeSet<>(utils.makePackageComparator()); + packages = new TreeSet<>(utils.comparators.makePackageComparator()); // add all the included packages packages.addAll(includedPackageElements); }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ClassWriter.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ClassWriter.java Fri Apr 10 17:10:22 2020 +0000 @@ -172,6 +172,21 @@ Content getMemberTreeHeader(); /** + * Returns a list to be used for the list of details for members of a given kind. + * + * @return a list to be used for the list of details for members of a given kind + */ + Content getDetailsList(); + + /** + * Returns an item for the list of details for members of a given kind. + * + * @param content content for the item + * @return an item for the list of details for members of a given kind + */ + Content getDetailsListItem(Content content); + + /** * Add the class content tree. * * @param classContentTree class content tree which will be added to the content tree
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Fri Apr 10 17:10:22 2020 +0000 @@ -445,8 +445,8 @@ NewSerializedForm(Utils utils, Elements elements, TypeElement te) { this.utils = utils; this.elements = elements; - methods = new TreeSet<>(utils.makeGeneralPurposeComparator()); - fields = new TreeSet<>(utils.makeGeneralPurposeComparator()); + methods = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator()); + fields = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator()); if (utils.isExternalizable(te)) { /* look up required public accessible methods, * writeExternal and readExternal.
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java Fri Apr 10 17:10:22 2020 +0000 @@ -78,7 +78,7 @@ AnnotationTypeRequiredMemberWriter writer, VisibleMemberTable.Kind memberType) { super(context, typeElement); - this.writer = writer; + this.writer = Objects.requireNonNull(writer); this.members = getVisibleMembers(memberType); } @@ -126,16 +126,13 @@ /** * Build the member documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if an error occurs */ - protected void buildAnnotationTypeMember(Content memberDetailsTree) + protected void buildAnnotationTypeMember(Content detailsList) throws DocletException { - if (writer == null) { - return; - } if (hasMembersToDocument()) { - writer.addAnnotationDetailsMarker(memberDetailsTree); + writer.addAnnotationDetailsMarker(detailsList); Content annotationDetailsTreeHeader = writer.getAnnotationDetailsTreeHeader(); Content memberList = writer.getMemberList(); @@ -147,7 +144,8 @@ memberList.add(writer.getMemberListItem(annotationDocTree)); } - memberDetailsTree.add(writer.getAnnotationDetails(annotationDetailsTreeHeader, memberList)); + Content annotationDetails = writer.getAnnotationDetails(annotationDetailsTreeHeader, memberList); + detailsList.add(annotationDetails); } }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java Fri Apr 10 17:10:22 2020 +0000 @@ -335,67 +335,67 @@ * @throws DocletException if there is a problem while building the documentation */ protected void buildMemberDetails(Content classContentTree) throws DocletException { - Content memberDetailsTree = writer.getMemberTreeHeader(); + Content detailsList = writer.getDetailsList(); - buildEnumConstantsDetails(memberDetailsTree); - buildPropertyDetails(memberDetailsTree); - buildFieldDetails(memberDetailsTree); - buildConstructorDetails(memberDetailsTree); - buildAnnotationTypeRequiredMemberDetails(memberDetailsTree); - buildAnnotationTypeOptionalMemberDetails(memberDetailsTree); - buildMethodDetails(memberDetailsTree); + buildEnumConstantsDetails(detailsList); + buildPropertyDetails(detailsList); + buildFieldDetails(detailsList); + buildConstructorDetails(detailsList); + buildAnnotationTypeRequiredMemberDetails(detailsList); + buildAnnotationTypeOptionalMemberDetails(detailsList); + buildMethodDetails(detailsList); - classContentTree.add(writer.getMemberDetailsTree(memberDetailsTree)); + classContentTree.add(writer.getMemberDetailsTree(detailsList)); } /** * Build the enum constants documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if there is a problem while building the documentation */ - protected void buildEnumConstantsDetails(Content memberDetailsTree) throws DocletException { - builderFactory.getEnumConstantsBuilder(writer).build(memberDetailsTree); + protected void buildEnumConstantsDetails(Content detailsList) throws DocletException { + builderFactory.getEnumConstantsBuilder(writer).build(detailsList); } /** * Build the field documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if there is a problem while building the documentation */ - protected void buildFieldDetails(Content memberDetailsTree) throws DocletException { - builderFactory.getFieldBuilder(writer).build(memberDetailsTree); + protected void buildFieldDetails(Content detailsList) throws DocletException { + builderFactory.getFieldBuilder(writer).build(detailsList); } /** * Build the property documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if there is a problem while building the documentation */ - public void buildPropertyDetails( Content memberDetailsTree) throws DocletException { - builderFactory.getPropertyBuilder(writer).build(memberDetailsTree); + public void buildPropertyDetails( Content detailsList) throws DocletException { + builderFactory.getPropertyBuilder(writer).build(detailsList); } /** * Build the constructor documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if there is a problem while building the documentation */ - protected void buildConstructorDetails(Content memberDetailsTree) throws DocletException { - builderFactory.getConstructorBuilder(writer).build(memberDetailsTree); + protected void buildConstructorDetails(Content detailsList) throws DocletException { + builderFactory.getConstructorBuilder(writer).build(detailsList); } /** * Build the method documentation. * - * @param memberDetailsTree the content tree to which the documentation will be added + * @param detailsList the content tree to which the documentation will be added * @throws DocletException if there is a problem while building the documentation */ - protected void buildMethodDetails(Content memberDetailsTree) throws DocletException { - builderFactory.getMethodBuilder(writer).build(memberDetailsTree); + protected void buildMethodDetails(Content detailsList) throws DocletException { + builderFactory.getMethodBuilder(writer).build(detailsList); } /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ConstantsSummaryBuilder.java Tue Apr 07 18:30:32 2020 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ConstantsSummaryBuilder.java Fri Apr 10 17:10:22 2020 +0000 @@ -96,7 +96,7 @@ super(context); this.writer = writer; this.typeElementsWithConstFields = new HashSet<>(); - this.printedPackageHeaders = new TreeSet<>(utils.makePackageComparator()); + this.printedPackageHeaders = new TreeSet<>(utils.comparators.makePackageComparator()); } /** @@ -315,7 +315,7 @@ members.addAll(vmt.getVisibleMembers(FIELDS)); members.addAll(vmt.getVisibleMembers(ENUM_CONSTANTS)); SortedSet<VariableElement> includes = - new TreeSet<>(utils.makeGeneralPurposeComparator()); + new TreeSet<>(utils.comparators.makeGeneralPurposeComparator()); for (Element element : members) {<