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>&#64;</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>,&nbsp;<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&trade; 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&trade; 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 &le; 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>*&#47;</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>*&#47;</code>" are removed.  For lines
+     * the comment as it appears in source code.  The leading "{@code /**}"
+     * and trailing "<code>*&#47;</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) {<