changeset 55170:cfe047f11020 patterns-stage-1

Automatic merge with default
author mcimadamore
date Thu, 28 Feb 2019 22:05:33 +0100
parents 1e4a2079302b 1542e63eb537
children 966f6454ccd8 db99258b6011 285e83b11b53
files src/hotspot/share/prims/evmCompat.cpp src/hotspot/share/utilities/intHisto.cpp src/hotspot/share/utilities/intHisto.hpp src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING src/jdk.javadoc/share/classes/com/sun/javadoc/AnnotatedType.java src/jdk.javadoc/share/classes/com/sun/javadoc/AnnotationDesc.java src/jdk.javadoc/share/classes/com/sun/javadoc/AnnotationTypeDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/AnnotationTypeElementDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/AnnotationValue.java src/jdk.javadoc/share/classes/com/sun/javadoc/ClassDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/ConstructorDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/Doc.java src/jdk.javadoc/share/classes/com/sun/javadoc/DocErrorReporter.java src/jdk.javadoc/share/classes/com/sun/javadoc/Doclet.java src/jdk.javadoc/share/classes/com/sun/javadoc/ExecutableMemberDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/FieldDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/LanguageVersion.java src/jdk.javadoc/share/classes/com/sun/javadoc/MemberDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/MethodDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/PackageDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/ParamTag.java src/jdk.javadoc/share/classes/com/sun/javadoc/Parameter.java src/jdk.javadoc/share/classes/com/sun/javadoc/ParameterizedType.java src/jdk.javadoc/share/classes/com/sun/javadoc/ProgramElementDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/RootDoc.java src/jdk.javadoc/share/classes/com/sun/javadoc/SeeTag.java src/jdk.javadoc/share/classes/com/sun/javadoc/SerialFieldTag.java src/jdk.javadoc/share/classes/com/sun/javadoc/SourcePosition.java src/jdk.javadoc/share/classes/com/sun/javadoc/Tag.java src/jdk.javadoc/share/classes/com/sun/javadoc/ThrowsTag.java src/jdk.javadoc/share/classes/com/sun/javadoc/Type.java src/jdk.javadoc/share/classes/com/sun/javadoc/TypeVariable.java src/jdk.javadoc/share/classes/com/sun/javadoc/WildcardType.java src/jdk.javadoc/share/classes/com/sun/javadoc/package-info.java src/jdk.javadoc/share/classes/com/sun/tools/doclets/standard/Standard.java src/jdk.javadoc/share/classes/com/sun/tools/doclets/standard/package-info.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Main.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AbstractTypeImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotatedTypeImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationDescImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeElementDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationValueImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Comment.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ConstructorDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocLocale.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocletInvoker.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ExecutableMemberDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/FieldDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavaScriptScanner.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocClassFinder.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocMemberEnter.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTodo.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MemberDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MethodDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ModifierFilter.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PackageDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParamTagImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterizedTypeImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PrimitiveType.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ProgramElementDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SeeTagImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerialFieldTagImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerializedForm.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SourcePositionImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TagImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ThrowsTagImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeMaker.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeVariableImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/WildcardTypeImpl.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/package-info.java src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Headings.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MarkerComments.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java test/hotspot/gtest/memory/test_virtualSpaceNode.cpp test/jdk/tools/jlink/plugins/StripDebugPluginTest.java test/langtools/jdk/javadoc/lib/javadoc/tester/ShowHeadings.java test/langtools/jdk/javadoc/tool/api/basic/GetTask_DocletClassTest.java test/langtools/tools/javadoc/6176978/T6176978.java test/langtools/tools/javadoc/6176978/X.java test/langtools/tools/javadoc/6227454/Test.java test/langtools/tools/javadoc/6942366/T6942366.java test/langtools/tools/javadoc/6942366/Test.java test/langtools/tools/javadoc/6942366/p/Base.java test/langtools/tools/javadoc/6958836/Test.java test/langtools/tools/javadoc/6964914/Error.java test/langtools/tools/javadoc/6964914/JavacWarning.java test/langtools/tools/javadoc/6964914/JavadocWarning.java test/langtools/tools/javadoc/6964914/Test.java test/langtools/tools/javadoc/6964914/TestStdDoclet.java test/langtools/tools/javadoc/6964914/TestUserDoclet.java test/langtools/tools/javadoc/8025693/Test.java test/langtools/tools/javadoc/8147801/T8147801.java test/langtools/tools/javadoc/8147801/jarsrc/lib/Lib1.java test/langtools/tools/javadoc/8147801/jarsrc/lib/Lib2.java test/langtools/tools/javadoc/8147801/p/Test.java test/langtools/tools/javadoc/AddOpensTest.java test/langtools/tools/javadoc/BadOptionsTest.java test/langtools/tools/javadoc/BooleanConst.java test/langtools/tools/javadoc/BreakIteratorWarning.java test/langtools/tools/javadoc/CheckResourceKeys.java test/langtools/tools/javadoc/CompletionError.java test/langtools/tools/javadoc/EncodingTest.java test/langtools/tools/javadoc/FlagsTooEarly.java test/langtools/tools/javadoc/InlineTagsWithBraces.java test/langtools/tools/javadoc/LangVers.java test/langtools/tools/javadoc/MaxWarns.java test/langtools/tools/javadoc/MethodLinks.java test/langtools/tools/javadoc/NoStar.java test/langtools/tools/javadoc/ReleaseOption.java test/langtools/tools/javadoc/ReleaseOptionSource.java test/langtools/tools/javadoc/T4994049/FileWithTabs.java test/langtools/tools/javadoc/T4994049/T4994049.java test/langtools/tools/javadoc/T6968833.java test/langtools/tools/javadoc/XWerror.java test/langtools/tools/javadoc/annotations/annotateMethodsFields/Main.java test/langtools/tools/javadoc/annotations/annotateMethodsFields/expected.out test/langtools/tools/javadoc/annotations/annotateMethodsFields/pkg1/A.java test/langtools/tools/javadoc/annotations/annotateMethodsFields/pkg1/B.java test/langtools/tools/javadoc/annotations/annotateMethodsFields/pkg1/E.java test/langtools/tools/javadoc/annotations/annotatePackage/Main.java test/langtools/tools/javadoc/annotations/annotatePackage/expected.out test/langtools/tools/javadoc/annotations/annotatePackage/pkg1/A.java test/langtools/tools/javadoc/annotations/annotatePackage/pkg1/package-info.java test/langtools/tools/javadoc/annotations/annotatePackage/pkg1/package.html test/langtools/tools/javadoc/annotations/annotatePackage/pkg2/B.java test/langtools/tools/javadoc/annotations/annotatePackage/pkg2/package.html test/langtools/tools/javadoc/annotations/annotateParams/Main.java test/langtools/tools/javadoc/annotations/annotateParams/expected.out test/langtools/tools/javadoc/annotations/annotateParams/pkg1/A.java test/langtools/tools/javadoc/annotations/annotateParams/pkg1/C.java test/langtools/tools/javadoc/annotations/badVals/Main.java test/langtools/tools/javadoc/annotations/badVals/pkg1/A.java test/langtools/tools/javadoc/annotations/defaults/Main.java test/langtools/tools/javadoc/annotations/defaults/expected.out test/langtools/tools/javadoc/annotations/defaults/pkg1/A.java test/langtools/tools/javadoc/annotations/defaults/pkg1/B.java test/langtools/tools/javadoc/annotations/elementTypes/Main.java test/langtools/tools/javadoc/annotations/elementTypes/expected.out test/langtools/tools/javadoc/annotations/elementTypes/pkg1/A.java test/langtools/tools/javadoc/annotations/elementTypes/pkg1/B.java test/langtools/tools/javadoc/annotations/missing/Main.java test/langtools/tools/javadoc/annotations/missing/somepackage/MissingAnnotationClass.java test/langtools/tools/javadoc/annotations/shortcuts/Main.java test/langtools/tools/javadoc/annotations/shortcuts/expected.out test/langtools/tools/javadoc/annotations/shortcuts/pkg1/A.java test/langtools/tools/javadoc/annotations/shortcuts/pkg1/Array.java test/langtools/tools/javadoc/annotations/shortcuts/pkg1/Marker.java test/langtools/tools/javadoc/annotations/shortcuts/pkg1/Value.java test/langtools/tools/javadoc/api/basic/APITest.java test/langtools/tools/javadoc/api/basic/DocletPathTest.java test/langtools/tools/javadoc/api/basic/DocumentationToolLocationTest.java test/langtools/tools/javadoc/api/basic/GetSourceVersionsTest.java test/langtools/tools/javadoc/api/basic/GetTask_DiagListenerTest.java test/langtools/tools/javadoc/api/basic/GetTask_DocletClassTest.java test/langtools/tools/javadoc/api/basic/GetTask_FileManagerTest.java test/langtools/tools/javadoc/api/basic/GetTask_FileObjectsTest.java test/langtools/tools/javadoc/api/basic/GetTask_OptionsTest.java test/langtools/tools/javadoc/api/basic/GetTask_WriterTest.java test/langtools/tools/javadoc/api/basic/Task_reuseTest.java test/langtools/tools/javadoc/api/basic/pkg/C.java test/langtools/tools/javadoc/api/basic/taglets/UnderlineTaglet.java test/langtools/tools/javadoc/completionFailure/CompletionFailure.java test/langtools/tools/javadoc/completionFailure/pkg/A.java test/langtools/tools/javadoc/completionFailure/pkg/B.java test/langtools/tools/javadoc/dupOk/DupOk.java test/langtools/tools/javadoc/dupOk/sp1/p/A.java test/langtools/tools/javadoc/dupOk/sp2/p/A.java test/langtools/tools/javadoc/dupOk/sp2/p/B.java test/langtools/tools/javadoc/enum/docComments/Main.java test/langtools/tools/javadoc/enum/docComments/pkg1/Operation.java test/langtools/tools/javadoc/enum/enumType/Main.java test/langtools/tools/javadoc/enum/enumType/expected.out test/langtools/tools/javadoc/enum/enumType/pkg1/QuotablePerson.java test/langtools/tools/javadoc/generics/genericClass/Main.java test/langtools/tools/javadoc/generics/genericClass/expected.out test/langtools/tools/javadoc/generics/genericClass/pkg1/A.java test/langtools/tools/javadoc/generics/genericInnerAndOuter/Main.java test/langtools/tools/javadoc/generics/genericInnerAndOuter/expected.out test/langtools/tools/javadoc/generics/genericInnerAndOuter/pkg1/O.java test/langtools/tools/javadoc/generics/genericInnerAndOuter/pkg1/X.java test/langtools/tools/javadoc/generics/genericInterface/Main.java test/langtools/tools/javadoc/generics/genericInterface/expected.out test/langtools/tools/javadoc/generics/genericInterface/pkg1/A.java test/langtools/tools/javadoc/generics/genericMethod/Main.java test/langtools/tools/javadoc/generics/genericMethod/expected.out test/langtools/tools/javadoc/generics/genericMethod/pkg1/A.java test/langtools/tools/javadoc/generics/genericSuper/Main.java test/langtools/tools/javadoc/generics/genericSuper/expected.out test/langtools/tools/javadoc/generics/genericSuper/pkg1/A.java test/langtools/tools/javadoc/generics/supertypes/Main.java test/langtools/tools/javadoc/generics/supertypes/expected.out test/langtools/tools/javadoc/generics/supertypes/pkg1/A.java test/langtools/tools/javadoc/generics/supertypes/pkg1/B.java test/langtools/tools/javadoc/generics/throwsGeneric/Main.java test/langtools/tools/javadoc/generics/throwsGeneric/expected.out test/langtools/tools/javadoc/generics/throwsGeneric/pkg1/A.java test/langtools/tools/javadoc/generics/tparamCycle/Main.java test/langtools/tools/javadoc/generics/tparamCycle/pkg1/LikeEnum.java test/langtools/tools/javadoc/generics/tparamTagOnMethod/Main.java test/langtools/tools/javadoc/generics/tparamTagOnMethod/expected.out test/langtools/tools/javadoc/generics/tparamTagOnMethod/pkg1/A.java test/langtools/tools/javadoc/generics/tparamTagOnType/Main.java test/langtools/tools/javadoc/generics/tparamTagOnType/expected.out test/langtools/tools/javadoc/generics/tparamTagOnType/pkg1/A.java test/langtools/tools/javadoc/generics/wildcards/Main.java test/langtools/tools/javadoc/generics/wildcards/expected.out test/langtools/tools/javadoc/generics/wildcards/pkg1/A.java test/langtools/tools/javadoc/imports/I.java test/langtools/tools/javadoc/imports/MissingImport.java test/langtools/tools/javadoc/lib/OldToolTester.java test/langtools/tools/javadoc/lib/ToyDoclet.java test/langtools/tools/javadoc/nestedClass/NestedClass.java test/langtools/tools/javadoc/nestedClass/NestedClassB.java test/langtools/tools/javadoc/nonConstExprs/Test.java test/langtools/tools/javadoc/outputRedirect/Test.java test/langtools/tools/javadoc/outputRedirect/p/OutputRedirect.java test/langtools/tools/javadoc/parser/7091528/T7091528.java test/langtools/tools/javadoc/parser/7091528/p/C1.java test/langtools/tools/javadoc/parser/7091528/p/C3.java test/langtools/tools/javadoc/parser/7091528/p/q/C2.java test/langtools/tools/javadoc/sourceOnly/Test.java test/langtools/tools/javadoc/sourceOnly/p/NonSource.jasm test/langtools/tools/javadoc/sourceOnly/p/SourceOnly.java test/langtools/tools/javadoc/sourceOption/SourceOption.java test/langtools/tools/javadoc/sourceOption/p/LambdaConstructTest.java test/langtools/tools/javadoc/subpackageIgnore/SubpackageIgnore.java test/langtools/tools/javadoc/subpackageIgnore/pkg1/not-subpkg/SomeJavaFile.java test/langtools/tools/javadoc/varArgs/Main.java test/langtools/tools/javadoc/varArgs/expected.out test/langtools/tools/javadoc/varArgs/pkg1/A.java
diffstat 538 files changed, 5770 insertions(+), 30560 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Feb 22 14:51:06 2019 +0100
+++ b/.hgtags	Thu Feb 28 22:05:33 2019 +0100
@@ -546,3 +546,4 @@
 4ce47bc1fb92cf94c6e3d1f49d582f02dcb851ab jdk-12+32
 c081f3ea6b9300265a4a34e38f970b1e3ddaae9f jdk-13+9
 b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12+33
+8e069f7b4fabfe05d9f500783e6d56cb0196d25c jdk-13+10
--- a/make/data/cldr/common/main/my.xml	Fri Feb 22 14:51:06 2019 +0100
+++ b/make/data/cldr/common/main/my.xml	Thu Feb 28 22:05:33 2019 +0100
@@ -1446,17 +1446,14 @@
 							<pattern>z HH:mm:ss</pattern>
 						</timeFormat>
 					</timeFormatLength>
-					<!--Pattern for medium and short replaced with CLDR 29's patterns 
-					    as character 'B' is currently not supported in SimpleDateFormat and java.time.DateTimeFormatter 
-					    classes. This is a restriction until JDK-8209175 is resolved.-->
 					<timeFormatLength type="medium">
 						<timeFormat>
-							<pattern>HH:mm:ss</pattern>
+							<pattern>B HH:mm:ss</pattern>
 						</timeFormat>
 					</timeFormatLength>
 					<timeFormatLength type="short">
 						<timeFormat>
-							<pattern>H:mm</pattern>
+							<pattern>B H:mm</pattern>
 						</timeFormat>
 					</timeFormatLength>
 				</timeFormats>
--- a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -523,36 +523,46 @@
         for (String k : patternKeys) {
             if (myMap.containsKey(calendarPrefix + k)) {
                 int len = patternKeys.length;
-                List<String> rawPatterns = new ArrayList<>(len);
-                List<String> patterns = new ArrayList<>(len);
+                List<String> dateTimePatterns = new ArrayList<>(len);
+                List<String> sdfPatterns = new ArrayList<>(len);
                 for (int i = 0; i < len; i++) {
                     String key = calendarPrefix + patternKeys[i];
                     String pattern = (String) myMap.remove(key);
                     if (pattern == null) {
                         pattern = (String) parentsMap.remove(key);
                     }
-                    rawPatterns.add(i, pattern);
                     if (pattern != null) {
-                        patterns.add(i, translateDateFormatLetters(calendarType, pattern));
+                        // Perform date-time format pattern conversion which is
+                        // applicable to both SimpleDateFormat and j.t.f.DateTimeFormatter.
+                        // For example, character 'B' is mapped with 'a', as 'B' is not
+                        // supported in either SimpleDateFormat or j.t.f.DateTimeFormatter
+                        String transPattern = translateDateFormatLetters(calendarType, pattern, this::convertDateTimePatternLetter);
+                        dateTimePatterns.add(i, transPattern);
+                        // Additionally, perform SDF specific date-time format pattern conversion
+                        sdfPatterns.add(i, translateDateFormatLetters(calendarType, transPattern, this::convertSDFLetter));
                     } else {
-                        patterns.add(i, null);
+                        dateTimePatterns.add(i, null);
+                        sdfPatterns.add(i, null);
                     }
                 }
-                // If patterns is empty or has any nulls, discard patterns.
-                if (patterns.isEmpty()) {
+                // If empty, discard patterns
+                if (sdfPatterns.isEmpty()) {
                     return;
                 }
                 String key = calendarPrefix + name;
-                if (!rawPatterns.equals(patterns)) {
-                    myMap.put("java.time." + key, rawPatterns.toArray(new String[len]));
+
+                // If additional changes are made in the SDF specific conversion,
+                // keep the commonly converted patterns as java.time patterns
+                if (!dateTimePatterns.equals(sdfPatterns)) {
+                    myMap.put("java.time." + key, dateTimePatterns.toArray(String[]::new));
                 }
-                myMap.put(key, patterns.toArray(new String[len]));
+                myMap.put(key, sdfPatterns.toArray(new String[len]));
                 break;
             }
         }
     }
 
-    private String translateDateFormatLetters(CalendarType calendarType, String cldrFormat) {
+    private String translateDateFormatLetters(CalendarType calendarType, String cldrFormat, ConvertDateTimeLetters converter) {
         String pattern = cldrFormat;
         int length = pattern.length();
         boolean inQuote = false;
@@ -571,7 +581,7 @@
                     if (nextc == '\'') {
                         i++;
                         if (count != 0) {
-                            convert(calendarType, lastLetter, count, jrePattern);
+                            converter.convert(calendarType, lastLetter, count, jrePattern);
                             lastLetter = 0;
                             count = 0;
                         }
@@ -581,7 +591,7 @@
                 }
                 if (!inQuote) {
                     if (count != 0) {
-                        convert(calendarType, lastLetter, count, jrePattern);
+                        converter.convert(calendarType, lastLetter, count, jrePattern);
                         lastLetter = 0;
                         count = 0;
                     }
@@ -598,7 +608,7 @@
             }
             if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
                 if (count != 0) {
-                    convert(calendarType, lastLetter, count, jrePattern);
+                    converter.convert(calendarType, lastLetter, count, jrePattern);
                     lastLetter = 0;
                     count = 0;
                 }
@@ -611,7 +621,7 @@
                 count++;
                 continue;
             }
-            convert(calendarType, lastLetter, count, jrePattern);
+            converter.convert(calendarType, lastLetter, count, jrePattern);
             lastLetter = c;
             count = 1;
         }
@@ -621,7 +631,7 @@
         }
 
         if (count != 0) {
-            convert(calendarType, lastLetter, count, jrePattern);
+            converter.convert(calendarType, lastLetter, count, jrePattern);
         }
         if (cldrFormat.contentEquals(jrePattern)) {
             return cldrFormat;
@@ -676,71 +686,91 @@
         }
     }
 
-    private void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) {
+    /**
+     * Perform a generic conversion of CLDR date-time format pattern letter based
+     * on the support given by the SimpleDateFormat and the j.t.f.DateTimeFormatter
+     * for date-time formatting.
+     */
+    private void convertDateTimePatternLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) {
         switch (cldrLetter) {
-        case 'G':
-            if (calendarType != CalendarType.GREGORIAN) {
-                // Adjust the number of 'G's for JRE SimpleDateFormat
-                if (count == 5) {
-                    // CLDR narrow -> JRE short
-                    count = 1;
-                } else if (count == 1) {
-                    // CLDR abbr -> JRE long
-                    count = 4;
+            case 'u':
+                // Change cldr letter 'u' to 'y', as 'u' is interpreted as
+                // "Extended year (numeric)" in CLDR/LDML,
+                // which is not supported in SimpleDateFormat and
+                // j.t.f.DateTimeFormatter, so it is replaced with 'y'
+                // as the best approximation
+                appendN('y', count, sb);
+                break;
+            case 'B':
+                // 'B' character (day period) is not supported by
+                // SimpleDateFormat and j.t.f.DateTimeFormatter,
+                // this is a workaround in which 'B' character
+                // appearing in CLDR date-time pattern is replaced
+                // with 'a' character and hence resolved with am/pm strings.
+                // This workaround is based on the the fallback mechanism
+                // specified in LDML spec for 'B' character, when a locale
+                // does not have data for day period ('B')
+                appendN('a', count, sb);
+                break;
+            default:
+                appendN(cldrLetter, count, sb);
+                break;
+
+        }
+    }
+
+    /**
+     * Perform a conversion of CLDR date-time format pattern letter which is
+     * specific to the SimpleDateFormat.
+     */
+    private void convertSDFLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) {
+        switch (cldrLetter) {
+            case 'G':
+                if (calendarType != CalendarType.GREGORIAN) {
+                    // Adjust the number of 'G's for JRE SimpleDateFormat
+                    if (count == 5) {
+                        // CLDR narrow -> JRE short
+                        count = 1;
+                    } else if (count == 1) {
+                        // CLDR abbr -> JRE long
+                        count = 4;
+                    }
                 }
-            }
-            appendN(cldrLetter, count, sb);
-            break;
+                appendN(cldrLetter, count, sb);
+                break;
 
-        // TODO: support 'c' and 'e' in JRE SimpleDateFormat
-        // Use 'u' and 'E' for now.
-        case 'c':
-        case 'e':
-            switch (count) {
-            case 1:
-                sb.append('u');
+            // TODO: support 'c' and 'e' in JRE SimpleDateFormat
+            // Use 'u' and 'E' for now.
+            case 'c':
+            case 'e':
+                switch (count) {
+                    case 1:
+                        sb.append('u');
+                        break;
+                    case 3:
+                    case 4:
+                        appendN('E', count, sb);
+                        break;
+                    case 5:
+                        appendN('E', 3, sb);
+                        break;
+                }
                 break;
-            case 3:
-            case 4:
-                appendN('E', count, sb);
+
+            case 'v':
+            case 'V':
+                appendN('z', count, sb);
                 break;
-            case 5:
-                appendN('E', 3, sb);
+
+            case 'Z':
+                if (count == 4 || count == 5) {
+                    sb.append("XXX");
+                }
                 break;
-            }
-            break;
 
-        case 'l':
-            // 'l' is deprecated as a pattern character. Should be ignored.
-            break;
-
-        case 'u':
-            // Use 'y' for now.
-            appendN('y', count, sb);
-            break;
-
-        case 'v':
-        case 'V':
-            appendN('z', count, sb);
-            break;
-
-        case 'Z':
-            if (count == 4 || count == 5) {
-                sb.append("XXX");
-            }
-            break;
-
-        case 'U':
-        case 'q':
-        case 'Q':
-        case 'g':
-        case 'j':
-        case 'A':
-            throw new InternalError(String.format("Unsupported letter: '%c', count=%d, id=%s%n",
-                                                  cldrLetter, count, id));
-        default:
-            appendN(cldrLetter, count, sb);
-            break;
+            default:
+                appendN(cldrLetter, count, sb);
+                break;
         }
     }
 
@@ -758,4 +788,9 @@
         }
         return false;
     }
+
+    @FunctionalInterface
+    private interface ConvertDateTimeLetters {
+        void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb);
+    }
 }
--- a/make/lib/Awt2dLibraries.gmk	Fri Feb 22 14:51:06 2019 +0100
+++ b/make/lib/Awt2dLibraries.gmk	Thu Feb 28 22:05:33 2019 +0100
@@ -613,7 +613,8 @@
         type-limits missing-field-initializers implicit-fallthrough \
         strict-aliasing undef unused-function, \
     DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
-        maybe-uninitialized, \
+        maybe-uninitialized \
+        missing-attributes class-memaccess, \
     DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \
         tautological-constant-out-of-range-compare int-to-pointer-cast \
         sign-compare undef missing-field-initializers, \
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -2209,13 +2209,15 @@
     rf(Vn, 5), rf(Vd, 0);                                                               \
   }
 
-  INSN(addv, 0, 0b100001);
-  INSN(subv, 1, 0b100001);
-  INSN(mulv, 0, 0b100111);
-  INSN(mlav, 0, 0b100101);
-  INSN(mlsv, 1, 0b100101);
-  INSN(sshl, 0, 0b010001);
-  INSN(ushl, 1, 0b010001);
+  INSN(addv,   0, 0b100001);
+  INSN(subv,   1, 0b100001);
+  INSN(mulv,   0, 0b100111);
+  INSN(mlav,   0, 0b100101);
+  INSN(mlsv,   1, 0b100101);
+  INSN(sshl,   0, 0b010001);
+  INSN(ushl,   1, 0b010001);
+  INSN(umullv, 1, 0b110000);
+  INSN(umlalv, 1, 0b100000);
 
 #undef INSN
 
@@ -2227,13 +2229,14 @@
     rf(Vn, 5), rf(Vd, 0);                                                               \
   }
 
-  INSN(absr,  0, 0b100000101110);
-  INSN(negr,  1, 0b100000101110);
-  INSN(notr,  1, 0b100000010110);
-  INSN(addv,  0, 0b110001101110);
-  INSN(cls,   0, 0b100000010010);
-  INSN(clz,   1, 0b100000010010);
-  INSN(cnt,   0, 0b100000010110);
+  INSN(absr,   0, 0b100000101110);
+  INSN(negr,   1, 0b100000101110);
+  INSN(notr,   1, 0b100000010110);
+  INSN(addv,   0, 0b110001101110);
+  INSN(cls,    0, 0b100000010010);
+  INSN(clz,    1, 0b100000010010);
+  INSN(cnt,    0, 0b100000010110);
+  INSN(uaddlv, 1, 0b110000001110);
 
 #undef INSN
 
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -3257,11 +3257,14 @@
     Register buff   = c_rarg1;
     Register len    = c_rarg2;
     Register nmax  = r4;
-    Register base = r5;
+    Register base  = r5;
     Register count = r6;
     Register temp0 = rscratch1;
     Register temp1 = rscratch2;
-    Register temp2 = r7;
+    FloatRegister vbytes = v0;
+    FloatRegister vs1acc = v1;
+    FloatRegister vs2acc = v2;
+    FloatRegister vtable = v3;
 
     // Max number of bytes we can process before having to take the mod
     // 0x15B0 is 5552 in decimal, the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
@@ -3271,6 +3274,10 @@
     __ mov(base, BASE);
     __ mov(nmax, NMAX);
 
+    // Load accumulation coefficients for the upper 16 bits
+    __ lea(temp0, ExternalAddress((address) StubRoutines::aarch64::_adler_table));
+    __ ld1(vtable, __ T16B, Address(temp0));
+
     // s1 is initialized to the lower 16 bits of adler
     // s2 is initialized to the upper 16 bits of adler
     __ ubfx(s2, adler, 16, 16);  // s2 = ((adler >> 16) & 0xffff)
@@ -3311,53 +3318,8 @@
 
     __ bind(L_nmax_loop);
 
-    __ ldp(temp0, temp1, Address(__ post(buff, 16)));
-
-    __ add(s1, s1, temp0, ext::uxtb);
-    __ ubfx(temp2, temp0, 8, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 16, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 24, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 32, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 40, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 48, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp0, Assembler::LSR, 56);
-    __ add(s2, s2, s1);
-
-    __ add(s1, s1, temp1, ext::uxtb);
-    __ ubfx(temp2, temp1, 8, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 16, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 24, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 32, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 40, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 48, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp1, Assembler::LSR, 56);
-    __ add(s2, s2, s1);
+    generate_updateBytesAdler32_accum(s1, s2, buff, temp0, temp1,
+                                      vbytes, vs1acc, vs2acc, vtable);
 
     __ subs(count, count, 16);
     __ br(Assembler::HS, L_nmax_loop);
@@ -3400,53 +3362,8 @@
 
     __ bind(L_by16_loop);
 
-    __ ldp(temp0, temp1, Address(__ post(buff, 16)));
-
-    __ add(s1, s1, temp0, ext::uxtb);
-    __ ubfx(temp2, temp0, 8, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 16, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 24, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 32, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 40, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp0, 48, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp0, Assembler::LSR, 56);
-    __ add(s2, s2, s1);
-
-    __ add(s1, s1, temp1, ext::uxtb);
-    __ ubfx(temp2, temp1, 8, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 16, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 24, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 32, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 40, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ ubfx(temp2, temp1, 48, 8);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp2);
-    __ add(s2, s2, s1);
-    __ add(s1, s1, temp1, Assembler::LSR, 56);
-    __ add(s2, s2, s1);
+    generate_updateBytesAdler32_accum(s1, s2, buff, temp0, temp1,
+                                      vbytes, vs1acc, vs2acc, vtable);
 
     __ subs(len, len, 16);
     __ br(Assembler::HS, L_by16_loop);
@@ -3500,6 +3417,43 @@
     return start;
   }
 
+  void generate_updateBytesAdler32_accum(Register s1, Register s2, Register buff,
+          Register temp0, Register temp1, FloatRegister vbytes,
+          FloatRegister vs1acc, FloatRegister vs2acc, FloatRegister vtable) {
+    // Below is a vectorized implementation of updating s1 and s2 for 16 bytes.
+    // We use b1, b2, ..., b16 to denote the 16 bytes loaded in each iteration.
+    // In non-vectorized code, we update s1 and s2 as:
+    //   s1 <- s1 + b1
+    //   s2 <- s2 + s1
+    //   s1 <- s1 + b2
+    //   s2 <- s2 + b1
+    //   ...
+    //   s1 <- s1 + b16
+    //   s2 <- s2 + s1
+    // Putting above assignments together, we have:
+    //   s1_new = s1 + b1 + b2 + ... + b16
+    //   s2_new = s2 + (s1 + b1) + (s1 + b1 + b2) + ... + (s1 + b1 + b2 + ... + b16)
+    //          = s2 + s1 * 16 + (b1 * 16 + b2 * 15 + ... + b16 * 1)
+    //          = s2 + s1 * 16 + (b1, b2, ... b16) dot (16, 15, ... 1)
+    __ ld1(vbytes, __ T16B, Address(__ post(buff, 16)));
+
+    // s2 = s2 + s1 * 16
+    __ add(s2, s2, s1, Assembler::LSL, 4);
+
+    // vs1acc = b1 + b2 + b3 + ... + b16
+    // vs2acc = (b1 * 16) + (b2 * 15) + (b3 * 14) + ... + (b16 * 1)
+    __ umullv(vs2acc, __ T8B, vtable, vbytes);
+    __ umlalv(vs2acc, __ T16B, vtable, vbytes);
+    __ uaddlv(vs1acc, __ T16B, vbytes);
+    __ uaddlv(vs2acc, __ T8H, vs2acc);
+
+    // s1 = s1 + vs1acc, s2 = s2 + vs2acc
+    __ fmovd(temp0, vs1acc);
+    __ fmovd(temp1, vs2acc);
+    __ add(s1, s1, temp0);
+    __ add(s2, s2, temp1);
+  }
+
   /**
    *  Arguments:
    *
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -287,6 +287,11 @@
     0xD502ED78UL, 0xAE7D62EDUL,         // byte swap of word swap
 };
 
+// Accumulation coefficients for adler32 upper 16 bits
+jubyte StubRoutines::aarch64::_adler_table[] __attribute__ ((aligned(64))) = {
+    16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
+};
+
 juint StubRoutines::aarch64::_npio2_hw[] __attribute__ ((aligned(64))) = {
     // first, various coefficient values: 0.5, invpio2, pio2_1, pio2_1t, pio2_2,
     // pio2_2t, pio2_3, pio2_3t
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -186,6 +186,7 @@
 
 private:
   static juint    _crc_table[];
+  static jubyte   _adler_table[];
   // begin trigonometric tables block. See comments in .cpp file
   static juint    _npio2_hw[];
   static jdouble   _two_over_pi[];
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -2981,7 +2981,7 @@
   {
     Label notVolatile;
     __ tbz(r3, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
-    __ membar(MacroAssembler::StoreStore);
+    __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore);
     __ bind(notVolatile);
   }
 
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -258,8 +258,10 @@
   if (FLAG_IS_DEFAULT(UseCRC32)) {
     UseCRC32 = (auxv & HWCAP_CRC32) != 0;
   }
+
   if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) {
     warning("UseCRC32 specified, but not supported on this CPU");
+    FLAG_SET_DEFAULT(UseCRC32, false);
   }
 
   if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
@@ -277,6 +279,7 @@
   } else {
     if (UseLSE) {
       warning("UseLSE specified, but not supported on this CPU");
+      FLAG_SET_DEFAULT(UseLSE, false);
     }
   }
 
@@ -291,9 +294,11 @@
   } else {
     if (UseAES) {
       warning("UseAES specified, but not supported on this CPU");
+      FLAG_SET_DEFAULT(UseAES, false);
     }
     if (UseAESIntrinsics) {
       warning("UseAESIntrinsics specified, but not supported on this CPU");
+      FLAG_SET_DEFAULT(UseAESIntrinsics, false);
     }
   }
 
--- a/src/hotspot/cpu/x86/stubRoutines_x86.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -33,7 +33,7 @@
 
 enum platform_dependent_constants {
   code_size1 = 20000 LP64_ONLY(+10000),         // simply increase if too small (assembler will crash if too small)
-  code_size2 = 35300 LP64_ONLY(+10000)          // simply increase if too small (assembler will crash if too small)
+  code_size2 = 35300 LP64_ONLY(+11000)          // simply increase if too small (assembler will crash if too small)
 };
 
 class x86 {
--- a/src/hotspot/os/aix/os_aix.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/aix/os_aix.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -27,6 +27,7 @@
 #define OS_AIX_OS_AIX_INLINE_HPP
 
 #include "runtime/os.hpp"
+#include "os_posix.inline.hpp"
 
 // System includes
 
--- a/src/hotspot/os/bsd/os_bsd.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -37,6 +37,7 @@
 #include "memory/filemap.hpp"
 #include "oops/oop.inline.hpp"
 #include "os_bsd.inline.hpp"
+#include "os_posix.inline.hpp"
 #include "os_share_bsd.hpp"
 #include "prims/jniFastGetField.hpp"
 #include "prims/jvm_misc.hpp"
--- a/src/hotspot/os/bsd/os_bsd.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/bsd/os_bsd.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -26,6 +26,7 @@
 #define OS_BSD_OS_BSD_INLINE_HPP
 
 #include "runtime/os.hpp"
+#include "os_posix.inline.hpp"
 
 // System includes
 
--- a/src/hotspot/os/linux/os_linux.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -38,6 +38,7 @@
 #include "memory/filemap.hpp"
 #include "oops/oop.inline.hpp"
 #include "os_linux.inline.hpp"
+#include "os_posix.inline.hpp"
 #include "os_share_linux.hpp"
 #include "osContainer_linux.hpp"
 #include "prims/jniFastGetField.hpp"
@@ -1358,11 +1359,9 @@
 void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
-#ifndef ZERO
     if (DumpPrivateMappingsInCore) {
       ClassLoader::close_jrt_image();
     }
-#endif
 #ifndef PRODUCT
     fdStream out(defaultStream::output_fd());
     out.print_raw("Current thread is ");
--- a/src/hotspot/os/linux/os_perf_linux.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/linux/os_perf_linux.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1062,7 +1062,7 @@
 
   snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics/%s", iface, counter);
 
-  int fd = open(buf, O_RDONLY);
+  int fd = os::open(buf, O_RDONLY, 0);
   if (fd == -1) {
     return -1;
   }
--- a/src/hotspot/os/linux/perfMemory_linux.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/linux/perfMemory_linux.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -97,8 +97,8 @@
 
   int result;
 
-  RESTARTABLE(::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE),
-              result);;
+  RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR),
+              result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
@@ -871,7 +871,7 @@
   // Cannot use O_TRUNC here; truncation of an existing file has to happen
   // after the is_file_secure() check below.
   int result;
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
+  RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       if (errno == ELOOP) {
@@ -949,7 +949,7 @@
 
   // open the file
   int result;
-  RESTARTABLE(::open(filename, oflags), result);
+  RESTARTABLE(os::open(filename, oflags, 0), result);
   if (result == OS_ERR) {
     if (errno == ENOENT) {
       THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
--- a/src/hotspot/os/posix/os_posix.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/posix/os_posix.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -191,10 +191,6 @@
 
   os::native_path(fullname);
 
-  sigset_t set, oldset;
-  int ret = sigfillset(&set);
-  assert_with_errno(ret == 0, "sigfillset returned error");
-
   // set the file creation mask.
   mode_t file_mode = S_IRUSR | S_IWUSR;
 
@@ -208,7 +204,7 @@
   }
 
   // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted.
-  ret = unlink(fullname);
+  int ret = unlink(fullname);
   assert_with_errno(ret == 0, "unlink returned error");
 
   os::free(fullname);
@@ -2219,22 +2215,6 @@
   assert_status(status == 0, status, "mutex_destroy");
 }
 
-void os::PlatformMonitor::lock() {
-  int status = pthread_mutex_lock(&_mutex);
-  assert_status(status == 0, status, "mutex_lock");
-}
-
-void os::PlatformMonitor::unlock() {
-  int status = pthread_mutex_unlock(&_mutex);
-  assert_status(status == 0, status, "mutex_unlock");
-}
-
-bool os::PlatformMonitor::try_lock() {
-  int status = pthread_mutex_trylock(&_mutex);
-  assert_status(status == 0 || status == EBUSY, status, "mutex_trylock");
-  return status == 0;
-}
-
 // Must already be locked
 int os::PlatformMonitor::wait(jlong millis) {
   assert(millis >= 0, "negative timeout");
@@ -2263,14 +2243,4 @@
   }
 }
 
-void os::PlatformMonitor::notify() {
-  int status = pthread_cond_signal(&_cond);
-  assert_status(status == 0, status, "cond_signal");
-}
-
-void os::PlatformMonitor::notify_all() {
-  int status = pthread_cond_broadcast(&_cond);
-  assert_status(status == 0, status, "cond_broadcast");
-}
-
 #endif // !SOLARIS
--- a/src/hotspot/os/posix/os_posix.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/posix/os_posix.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -42,6 +42,39 @@
 inline int os::Posix::clock_getres(clockid_t clock_id, struct timespec *tp) {
   return _clock_getres != NULL ? _clock_getres(clock_id, tp) : -1;
 }
+
 #endif // SUPPORTS_CLOCK_MONOTONIC
 
+#ifndef SOLARIS
+
+// Platform Monitor implementation
+
+inline void os::PlatformMonitor::lock() {
+  int status = pthread_mutex_lock(&_mutex);
+  assert_status(status == 0, status, "mutex_lock");
+}
+
+inline void os::PlatformMonitor::unlock() {
+  int status = pthread_mutex_unlock(&_mutex);
+  assert_status(status == 0, status, "mutex_unlock");
+}
+
+inline bool os::PlatformMonitor::try_lock() {
+  int status = pthread_mutex_trylock(&_mutex);
+  assert_status(status == 0 || status == EBUSY, status, "mutex_trylock");
+  return status == 0;
+}
+
+inline void os::PlatformMonitor::notify() {
+  int status = pthread_cond_signal(&_cond);
+  assert_status(status == 0, status, "cond_signal");
+}
+
+inline void os::PlatformMonitor::notify_all() {
+  int status = pthread_cond_broadcast(&_cond);
+  assert_status(status == 0, status, "cond_broadcast");
+}
+
+#endif // !SOLARIS
+
 #endif // OS_POSIX_OS_POSIX_INLINE_HPP
--- a/src/hotspot/os/solaris/os_perf_solaris.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/solaris/os_perf_solaris.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -74,7 +74,7 @@
 
   int fd = -1;
 
-  if ((fd = open(path, O_RDONLY)) < 0) {
+  if ((fd = os::open(path, O_RDONLY, 0)) < 0) {
     return OS_ERR;
   }
   if (pread(fd, info, s, o) != s) {
--- a/src/hotspot/os/windows/os_windows.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -602,7 +602,7 @@
   HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
   if (interrupt_event == NULL) {
     delete osthread;
-    return NULL;
+    return false;
   }
   osthread->set_interrupt_event(interrupt_event);
   osthread->set_interrupted(false);
@@ -676,7 +676,7 @@
     CloseHandle(osthread->interrupt_event());
     thread->set_osthread(NULL);
     delete osthread;
-    return NULL;
+    return false;
   }
 
   Atomic::inc(&os::win32::_os_thread_count);
@@ -5320,27 +5320,6 @@
 
 // Platform Monitor implementation
 
-os::PlatformMonitor::PlatformMonitor() {
-  InitializeConditionVariable(&_cond);
-  InitializeCriticalSection(&_mutex);
-}
-
-os::PlatformMonitor::~PlatformMonitor() {
-  DeleteCriticalSection(&_mutex);
-}
-
-void os::PlatformMonitor::lock() {
-  EnterCriticalSection(&_mutex);
-}
-
-void os::PlatformMonitor::unlock() {
-  LeaveCriticalSection(&_mutex);
-}
-
-bool os::PlatformMonitor::try_lock() {
-  return TryEnterCriticalSection(&_mutex);
-}
-
 // Must already be locked
 int os::PlatformMonitor::wait(jlong millis) {
   assert(millis >= 0, "negative timeout");
@@ -5359,14 +5338,6 @@
   return ret;
 }
 
-void os::PlatformMonitor::notify() {
-  WakeConditionVariable(&_cond);
-}
-
-void os::PlatformMonitor::notify_all() {
-  WakeAllConditionVariable(&_cond);
-}
-
 // Run the specified command in a separate process. Return its exit value,
 // or -1 on failure (e.g. can't create a new process).
 int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
--- a/src/hotspot/os/windows/os_windows.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os/windows/os_windows.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -86,4 +86,35 @@
   win32::exit_process_or_thread(win32::EPT_PROCESS, num);
 }
 
+// Platform Monitor implementation
+
+inline os::PlatformMonitor::PlatformMonitor() {
+  InitializeConditionVariable(&_cond);
+  InitializeCriticalSection(&_mutex);
+}
+
+inline os::PlatformMonitor::~PlatformMonitor() {
+  DeleteCriticalSection(&_mutex);
+}
+
+inline void os::PlatformMonitor::lock() {
+  EnterCriticalSection(&_mutex);
+}
+
+inline void os::PlatformMonitor::unlock() {
+  LeaveCriticalSection(&_mutex);
+}
+
+inline bool os::PlatformMonitor::try_lock() {
+  return TryEnterCriticalSection(&_mutex);
+}
+
+inline void os::PlatformMonitor::notify() {
+  WakeConditionVariable(&_cond);
+}
+
+inline void os::PlatformMonitor::notify_all() {
+  WakeAllConditionVariable(&_cond);
+}
+
 #endif // OS_WINDOWS_OS_WINDOWS_INLINE_HPP
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -191,7 +191,7 @@
 
   // Try to create an anonymous file using the O_TMPFILE flag. Note that this
   // flag requires kernel >= 3.11. If this fails we fall back to open/unlink.
-  const int fd_anon = open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+  const int fd_anon = os::open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
   if (fd_anon == -1) {
     ZErrno err;
     log_debug(gc, init)("Failed to create anonymous file in %s (%s)", path.get(),
@@ -217,7 +217,7 @@
   snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id());
 
   // Create file
-  const int fd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+  const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
   if (fd == -1) {
     ZErrno err;
     log_error(gc, init)("Failed to create file %s (%s)", filename, err.to_string());
--- a/src/hotspot/share/ci/ciEnv.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/ci/ciEnv.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1253,7 +1253,7 @@
   static char buffer[O_BUFLEN];
   int ret = jio_snprintf(buffer, O_BUFLEN, "replay_pid%p_compid%d.log", os::current_process_id(), compile_id);
   if (ret > 0) {
-    int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
+    int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
     if (fd != -1) {
       FILE* replay_data_file = os::open(fd, "w");
       if (replay_data_file != NULL) {
@@ -1271,7 +1271,7 @@
   static char buffer[O_BUFLEN];
   int ret = jio_snprintf(buffer, O_BUFLEN, "inline_pid%p_compid%d.log", os::current_process_id(), compile_id);
   if (ret > 0) {
-    int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
+    int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
     if (fd != -1) {
       FILE* inline_data_file = os::open(fd, "w");
       if (inline_data_file != NULL) {
--- a/src/hotspot/share/classfile/classFileParser.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -60,6 +60,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
 #include "runtime/perfData.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/safepointVerifiers.hpp"
@@ -5747,8 +5748,8 @@
     int class_name_len = _class_name->utf8_length();
     int symbol_len = host_pkg_len + 1 + class_name_len;
     char* new_anon_name = NEW_RESOURCE_ARRAY(char, symbol_len + 1);
-    int n = snprintf(new_anon_name, symbol_len + 1, "%s/%.*s",
-                     host_pkg_name, class_name_len, _class_name->base());
+    int n = os::snprintf(new_anon_name, symbol_len + 1, "%s/%.*s",
+                         host_pkg_name, class_name_len, _class_name->base());
     assert(n == symbol_len, "Unexpected number of characters in string");
 
     // Decrement old _class_name to avoid leaking.
--- a/src/hotspot/share/classfile/classLoader.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -620,13 +620,14 @@
   update_module_path_entry_list(path, THREAD);
 }
 
+#endif // INCLUDE_CDS
+
 void ClassLoader::close_jrt_image() {
-  assert(ClassLoader::has_jrt_entry(), "Not applicable for exploded builds");
+  // Not applicable for exploded builds
+  if (!ClassLoader::has_jrt_entry()) return;
   _jrt_entry->close_jimage();
 }
 
-#endif // INCLUDE_CDS
-
 // Construct the array of module/path pairs as specified to --patch-module
 // for the boot loader to search ahead of the jimage, if the class being
 // loaded is defined to a module that has been specified to --patch-module.
--- a/src/hotspot/share/classfile/classLoader.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/classLoader.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -247,12 +247,12 @@
 
   static void load_zip_library();
   static void load_jimage_library();
+
+ public:
   static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
                                                  bool throw_exception,
                                                  bool is_boot_append, TRAPS);
 
- public:
-
   // If the package for the fully qualified class name is in the boot
   // loader's package entry table then add_package() sets the classpath_index
   // field so that get_system_package() will know to return a non-null value
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -208,7 +208,7 @@
         ResourceMark rm(THREAD);
         size_t libname_len = dir_len + name_len;
         char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1);
-        int n = snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start);
+        int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start);
         assert((size_t)n == libname_len, "Unexpected number of characters in string");
         trace_class_path("library = ", libname);
         ClassLoader::update_class_path_entry_list(libname, true, false);
--- a/src/hotspot/share/classfile/compactHashtable.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/compactHashtable.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -198,7 +198,7 @@
     quit("Unable to get hashtable dump file size", filename);
   }
   _size = st.st_size;
-  _fd = open(filename, O_RDONLY | O_BINARY, 0);
+  _fd = os::open(filename, O_RDONLY | O_BINARY, 0);
   if (_fd < 0) {
     quit("Unable to open hashtable dump file", filename);
   }
--- a/src/hotspot/share/classfile/javaClasses.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -3635,7 +3635,7 @@
     // distinct loaders) to ensure the metadata is kept alive.
     // This mirror may be different than the one in clazz field.
     new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());
-    resolved_method = ResolvedMethodTable::add_method(Handle(THREAD, new_resolved_method));
+    resolved_method = ResolvedMethodTable::add_method(m, Handle(THREAD, new_resolved_method));
   }
   return resolved_method;
 }
--- a/src/hotspot/share/classfile/klassFactory.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/klassFactory.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -46,22 +46,22 @@
                                           InstanceKlass* ik,
                                           Symbol* class_name,
                                           Handle class_loader,
-                                          Handle protection_domain, TRAPS) {
+                                          Handle protection_domain,
+                                          const ClassFileStream *cfs,
+                                          TRAPS) {
 #if INCLUDE_CDS && INCLUDE_JVMTI
   assert(ik != NULL, "sanity");
   assert(ik->is_shared(), "expecting a shared class");
-
   if (JvmtiExport::should_post_class_file_load_hook()) {
     assert(THREAD->is_Java_thread(), "must be JavaThread");
 
     // Post the CFLH
     JvmtiCachedClassFileData* cached_class_file = NULL;
-    JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data();
-    assert(archived_class_data != NULL, "shared class has no archived class data");
-    unsigned char* ptr =
-        VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data);
-    unsigned char* end_ptr =
-        ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data);
+    if (cfs == NULL) {
+      cfs = FileMapInfo::open_stream_for_jvmti(ik, CHECK_NULL);
+    }
+    unsigned char* ptr = (unsigned char*)cfs->buffer();
+    unsigned char* end_ptr = ptr + cfs->length();
     unsigned char* old_ptr = ptr;
     JvmtiExport::post_class_file_load_hook(class_name,
                                            class_loader,
@@ -75,25 +75,9 @@
       ClassLoaderData* loader_data =
         ClassLoaderData::class_loader_data(class_loader());
       int path_index = ik->shared_classpath_index();
-      const char* pathname;
-      if (path_index < 0) {
-        // shared classes loaded by user defined class loader
-        // do not have shared_classpath_index
-        ModuleEntry* mod_entry = ik->module();
-        if (mod_entry != NULL && (mod_entry->location() != NULL)) {
-          ResourceMark rm;
-          pathname = (const char*)(mod_entry->location()->as_C_string());
-        } else {
-          pathname = "";
-        }
-      } else {
-        SharedClassPathEntry* ent =
-          (SharedClassPathEntry*)FileMapInfo::shared_path(path_index);
-        pathname = ent == NULL ? NULL : ent->name();
-      }
       ClassFileStream* stream = new ClassFileStream(ptr,
                                                     end_ptr - ptr,
-                                                    pathname,
+                                                    cfs->source(),
                                                     ClassFileStream::verify);
       ClassFileParser parser(stream,
                              class_name,
@@ -236,24 +220,6 @@
 #if INCLUDE_CDS
   if (DumpSharedSpaces) {
     ClassLoader::record_result(result, stream, THREAD);
-#if INCLUDE_JVMTI
-    assert(cached_class_file == NULL, "Sanity");
-    // Archive the class stream data into the optional data section
-    JvmtiCachedClassFileData *p;
-    int len;
-    const unsigned char *bytes;
-    // event based tracing might set cached_class_file
-    if ((bytes = result->get_cached_class_file_bytes()) != NULL) {
-      len = result->get_cached_class_file_len();
-    } else {
-      len = stream->length();
-      bytes = stream->buffer();
-    }
-    p = (JvmtiCachedClassFileData*)os::malloc(offset_of(JvmtiCachedClassFileData, data) + len, mtInternal);
-    p->length = len;
-    memcpy(p->data, bytes, len);
-    result->set_archived_class_data(p);
-#endif // INCLUDE_JVMTI
   }
 #endif // INCLUDE_CDS
 
--- a/src/hotspot/share/classfile/klassFactory.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/klassFactory.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -80,7 +80,9 @@
                                           InstanceKlass* ik,
                                           Symbol* class_name,
                                           Handle class_loader,
-                                          Handle protection_domain, TRAPS);
+                                          Handle protection_domain,
+                                          const ClassFileStream *cfs,
+                                          TRAPS);
 };
 
 #endif // SHARE_CLASSFILE_KLASSFACTORY_HPP
--- a/src/hotspot/share/classfile/symbolTable.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -436,18 +436,16 @@
   }
 }
 
-void SymbolTable::add(ClassLoaderData* loader_data, const constantPoolHandle& cp,
-                      int names_count, const char** names, int* lengths,
-                      int* cp_indices, unsigned int* hashValues, TRAPS) {
+void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp,
+                              int names_count, const char** names, int* lengths,
+                              int* cp_indices, unsigned int* hashValues, TRAPS) {
   bool c_heap = !loader_data->is_the_null_class_loader_data();
   for (int i = 0; i < names_count; i++) {
     const char *name = names[i];
     int len = lengths[i];
     unsigned int hash = hashValues[i];
-    Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
-    if (sym == NULL) {
-      sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
-    }
+    assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already");
+    Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
     assert(sym->refcount() != 0, "lookup should have incremented the count");
     cp->symbol_at_put(cp_indices[i], sym);
   }
--- a/src/hotspot/share/classfile/symbolTable.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -144,18 +144,11 @@
   Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS);
 
   // Adding elements
-  static void add(ClassLoaderData* loader_data,
-                  const constantPoolHandle& cp, int names_count,
-                  const char** names, int* lengths, int* cp_indices,
-                  unsigned int* hashValues, TRAPS);
-
   static void new_symbols(ClassLoaderData* loader_data,
                           const constantPoolHandle& cp, int names_count,
                           const char** name, int* lengths,
                           int* cp_indices, unsigned int* hashValues,
-                          TRAPS) {
-    add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
-  }
+                          TRAPS);
 
   static Symbol* lookup_shared(const char* name, int len, unsigned int hash);
   Symbol* lookup_dynamic(const char* name, int len, unsigned int hash);
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1174,7 +1174,7 @@
                                                         TRAPS) {
   InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
   if (ik != NULL && ik->is_shared_boot_class()) {
-    return load_shared_class(ik, Handle(), Handle(), THREAD);
+    return load_shared_class(ik, Handle(), Handle(), NULL, THREAD);
   }
   return NULL;
 }
@@ -1274,7 +1274,9 @@
 
 InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
                                                    Handle class_loader,
-                                                   Handle protection_domain, TRAPS) {
+                                                   Handle protection_domain,
+                                                   const ClassFileStream *cfs,
+                                                   TRAPS) {
 
   if (ik != NULL) {
     Symbol* class_name = ik->name();
@@ -1321,7 +1323,7 @@
     }
 
     InstanceKlass* new_ik = KlassFactory::check_shared_class_file_load_hook(
-        ik, class_name, class_loader, protection_domain, CHECK_NULL);
+        ik, class_name, class_loader, protection_domain, cfs, CHECK_NULL);
     if (new_ik != NULL) {
       // The class is changed by CFLH. Return the new class. The shared class is
       // not used.
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -628,6 +628,7 @@
   static InstanceKlass* load_shared_class(InstanceKlass* ik,
                                           Handle class_loader,
                                           Handle protection_domain,
+                                          const ClassFileStream *cfs,
                                           TRAPS);
   static InstanceKlass* load_shared_boot_class(Symbol* class_name,
                                                TRAPS);
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -803,7 +803,7 @@
          SystemDictionary::is_platform_class_loader(class_loader()))) {
       Handle protection_domain =
         SystemDictionaryShared::init_security_info(class_loader, ik, CHECK_NULL);
-      return load_shared_class(ik, class_loader, protection_domain, THREAD);
+      return load_shared_class(ik, class_loader, protection_domain, NULL, THREAD);
     }
   }
   return NULL;
@@ -873,13 +873,15 @@
   }
 
   return acquire_class_for_current_thread(record->_klass, class_loader,
-                                          protection_domain, THREAD);
+                                          protection_domain, cfs,
+                                          THREAD);
 }
 
 InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
                    InstanceKlass *ik,
                    Handle class_loader,
                    Handle protection_domain,
+                   const ClassFileStream *cfs,
                    TRAPS) {
   ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
 
@@ -900,7 +902,8 @@
   loader_data->add_class(ik);
 
   // Load and check super/interfaces, restore unsharable info
-  InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain, THREAD);
+  InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain,
+                                                  cfs, THREAD);
   if (shared_klass == NULL || HAS_PENDING_EXCEPTION) {
     // TODO: clean up <ik> so it can be used again
     return NULL;
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -207,6 +207,7 @@
                                  InstanceKlass *ik,
                                  Handle class_loader,
                                  Handle protection_domain,
+                                 const ClassFileStream* cfs,
                                  TRAPS);
   static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k);
   static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin);
--- a/src/hotspot/share/classfile/verifier.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/classfile/verifier.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -2982,14 +2982,14 @@
     // add one dimension to component
     length++;
     arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1);
-    int n = snprintf(arr_sig_str, length + 1, "[%s", component_name);
+    int n = os::snprintf(arr_sig_str, length + 1, "[%s", component_name);
     assert(n == length, "Unexpected number of characters in string");
   } else {         // it's an object or interface
     const char* component_name = component_type.name()->as_utf8();
     // add one dimension to component with 'L' prepended and ';' postpended.
     length = (int)strlen(component_name) + 3;
     arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1);
-    int n = snprintf(arr_sig_str, length + 1, "[L%s;", component_name);
+    int n = os::snprintf(arr_sig_str, length + 1, "[L%s;", component_name);
     assert(n == length, "Unexpected number of characters in string");
   }
   Symbol* arr_sig = create_temporary_symbol(
--- a/src/hotspot/share/code/nmethod.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/code/nmethod.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1370,6 +1370,8 @@
   assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie");
 #endif
 
+  Universe::heap()->flush_nmethod(this);
+
   CodeBlob::flush();
   CodeCache::free(this);
 }
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -48,7 +48,6 @@
 #include "runtime/os.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "utilities/intHisto.hpp"
 #include "utilities/stack.inline.hpp"
 #include "utilities/ticks.hpp"
 
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -521,6 +521,7 @@
   // Override with specific mechanism for each specialized heap type.
   virtual void register_nmethod(nmethod* nm) {}
   virtual void unregister_nmethod(nmethod* nm) {}
+  virtual void flush_nmethod(nmethod* nm) {}
   virtual void verify_nmethod(nmethod* nmethod) {}
 
   void trace_heap_before_gc(const GCTracer* gc_tracer);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -482,7 +482,9 @@
 class ShenandoahInitGCLABClosure : public ThreadClosure {
 public:
   void do_thread(Thread* thread) {
-    if (thread != NULL && (thread->is_Java_thread() || thread->is_Worker_thread())) {
+    assert(thread != NULL, "Sanity");
+    assert(!thread->is_Java_thread(), "Don't expect JavaThread this early");
+    if (thread->is_Worker_thread()) {
       ShenandoahThreadLocalData::initialize_gclab(thread);
     }
   }
@@ -494,8 +496,6 @@
 
   ShenandoahInitGCLABClosure init_gclabs;
   Threads::threads_do(&init_gclabs);
-  _workers->threads_do(&init_gclabs);
-  _safepoint_workers->threads_do(&init_gclabs);
 
   // gclab can not be initialized early during VM startup, as it can not determinate its max_size.
   // Now, we will let WorkGang to initialize gclab when new worker is created.
--- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
@@ -122,6 +122,7 @@
 
   static void initialize_gclab(Thread* thread) {
     assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs");
+    assert(data(thread)->_gclab == NULL, "Only initialize once");
     data(thread)->_gclab = new PLAB(PLAB::min_size());
     data(thread)->_gclab_size = 0;
   }
--- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -27,12 +27,12 @@
 #include "gc/z/zGlobals.hpp"
 #include "gc/z/zLock.inline.hpp"
 #include "gc/z/zOopClosures.hpp"
-#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNMethod.hpp"
 #include "gc/z/zThreadLocalData.hpp"
 #include "logging/log.hpp"
 
 bool ZBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) {
-  ZLocker<ZReentrantLock> locker(ZNMethodTable::lock_for_nmethod(nm));
+  ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
   log_trace(nmethod, barrier)("Entered critical zone for %p", nm);
 
   if (!is_armed(nm)) {
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -27,7 +27,7 @@
 #include "gc/z/zCollectedHeap.hpp"
 #include "gc/z/zGlobals.hpp"
 #include "gc/z/zHeap.inline.hpp"
-#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNMethod.hpp"
 #include "gc/z/zServiceability.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zUtils.inline.hpp"
@@ -255,11 +255,15 @@
 }
 
 void ZCollectedHeap::register_nmethod(nmethod* nm) {
-  ZNMethodTable::register_nmethod(nm);
+  ZNMethod::register_nmethod(nm);
 }
 
 void ZCollectedHeap::unregister_nmethod(nmethod* nm) {
-  ZNMethodTable::unregister_nmethod(nm);
+  ZNMethod::unregister_nmethod(nm);
+}
+
+void ZCollectedHeap::flush_nmethod(nmethod* nm) {
+  ZNMethod::flush_nmethod(nm);
 }
 
 void ZCollectedHeap::verify_nmethod(nmethod* nm) {
--- a/src/hotspot/share/gc/z/zCollectedHeap.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -105,6 +105,7 @@
 
   virtual void register_nmethod(nmethod* nm);
   virtual void unregister_nmethod(nmethod* nm);
+  virtual void flush_nmethod(nmethod* nm);
   virtual void verify_nmethod(nmethod* nmethod);
 
   virtual WorkGang* get_safepoint_workers();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethod.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "code/relocInfo.hpp"
+#include "code/nmethod.hpp"
+#include "code/icBuffer.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetNMethod.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLock.inline.hpp"
+#include "gc/z/zNMethod.hpp"
+#include "gc/z/zNMethodData.hpp"
+#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zWorkers.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/iterator.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+#include "utilities/debug.hpp"
+
+static ZNMethodData* gc_data(const nmethod* nm) {
+  return nm->gc_data<ZNMethodData>();
+}
+
+static void set_gc_data(nmethod* nm, ZNMethodData* data) {
+  return nm->set_gc_data<ZNMethodData>(data);
+}
+
+void ZNMethod::attach_gc_data(nmethod* nm) {
+  GrowableArray<oop*> immediate_oops;
+  bool non_immediate_oops = false;
+
+  // Find all oops relocations
+  RelocIterator iter(nm);
+  while (iter.next()) {
+    if (iter.type() != relocInfo::oop_type) {
+      // Not an oop
+      continue;
+    }
+
+    oop_Relocation* r = iter.oop_reloc();
+
+    if (!r->oop_is_immediate()) {
+      // Non-immediate oop found
+      non_immediate_oops = true;
+      continue;
+    }
+
+    if (r->oop_value() != NULL) {
+      // Non-NULL immediate oop found. NULL oops can safely be
+      // ignored since the method will be re-registered if they
+      // are later patched to be non-NULL.
+      immediate_oops.push(r->oop_addr());
+    }
+  }
+
+  // Attach GC data to nmethod
+  ZNMethodData* data = gc_data(nm);
+  if (data == NULL) {
+    data = new ZNMethodData();
+    set_gc_data(nm, data);
+  }
+
+  // Attach oops in GC data
+  ZNMethodDataOops* const new_oops = ZNMethodDataOops::create(immediate_oops, non_immediate_oops);
+  ZNMethodDataOops* const old_oops = data->swap_oops(new_oops);
+  ZNMethodDataOops::destroy(old_oops);
+}
+
+ZReentrantLock* ZNMethod::lock_for_nmethod(nmethod* nm) {
+  return gc_data(nm)->lock();
+}
+
+void ZNMethod::log_register(const nmethod* nm) {
+  LogTarget(Trace, gc, nmethod) log;
+  if (!log.is_enabled()) {
+    return;
+  }
+
+  const ZNMethodDataOops* const oops = gc_data(nm)->oops();
+
+  log.print("Register NMethod: %s.%s (" PTR_FORMAT "), "
+            "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s",
+            nm->method()->method_holder()->external_name(),
+            nm->method()->name()->as_C_string(),
+            p2i(nm),
+            nm->compiler_name(),
+            nm->oops_count() - 1,
+            oops->immediates_count(),
+            oops->has_non_immediates() ? "Yes" : "No");
+
+  LogTarget(Trace, gc, nmethod, oops) log_oops;
+  if (!log_oops.is_enabled()) {
+    return;
+  }
+
+  // Print nmethod oops table
+  {
+    oop* const begin = nm->oops_begin();
+    oop* const end = nm->oops_end();
+    for (oop* p = begin; p < end; p++) {
+      log_oops.print("           Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)",
+                     (p - begin), p2i(*p), (*p)->klass()->external_name());
+    }
+  }
+
+  // Print nmethod immediate oops
+  {
+    oop** const begin = oops->immediates_begin();
+    oop** const end = oops->immediates_end();
+    for (oop** p = begin; p < end; p++) {
+      log_oops.print("  ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)",
+                     (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name());
+    }
+  }
+}
+
+void ZNMethod::log_unregister(const nmethod* nm) {
+  LogTarget(Debug, gc, nmethod) log;
+  if (!log.is_enabled()) {
+    return;
+  }
+
+  log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")",
+            nm->method()->method_holder()->external_name(),
+            nm->method()->name()->as_C_string(),
+            p2i(nm));
+}
+
+void ZNMethod::register_nmethod(nmethod* nm) {
+  ResourceMark rm;
+
+  // Create and attach gc data
+  attach_gc_data(nm);
+
+  log_register(nm);
+
+  ZNMethodTable::register_nmethod(nm);
+
+  // Disarm nmethod entry barrier
+  disarm_nmethod(nm);
+}
+
+void ZNMethod::unregister_nmethod(nmethod* nm) {
+  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
+
+  if (Thread::current()->is_Code_cache_sweeper_thread()) {
+    // The sweeper must wait for any ongoing iteration to complete
+    // before it can unregister an nmethod.
+    ZNMethodTable::wait_until_iteration_done();
+  }
+
+  ResourceMark rm;
+
+  log_unregister(nm);
+
+  ZNMethodTable::unregister_nmethod(nm);
+}
+
+void ZNMethod::flush_nmethod(nmethod* nm) {
+  // Destroy GC data
+  delete gc_data(nm);
+}
+
+void ZNMethod::disarm_nmethod(nmethod* nm) {
+  BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
+  if (bs != NULL) {
+    bs->disarm(nm);
+  }
+}
+
+void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) {
+  // Process oops table
+  {
+    oop* const begin = nm->oops_begin();
+    oop* const end = nm->oops_end();
+    for (oop* p = begin; p < end; p++) {
+      if (*p != Universe::non_oop_word()) {
+        cl->do_oop(p);
+      }
+    }
+  }
+
+  ZNMethodDataOops* const oops = gc_data(nm)->oops();
+
+  // Process immediate oops
+  {
+    oop** const begin = oops->immediates_begin();
+    oop** const end = oops->immediates_end();
+    for (oop** p = begin; p < end; p++) {
+      if (**p != Universe::non_oop_word()) {
+        cl->do_oop(*p);
+      }
+    }
+  }
+
+  // Process non-immediate oops
+  if (oops->has_non_immediates()) {
+    nm->fix_oop_relocations();
+  }
+}
+
+class ZNMethodToOopsDoClosure : public NMethodClosure {
+private:
+  OopClosure* _cl;
+
+public:
+  ZNMethodToOopsDoClosure(OopClosure* cl) :
+      _cl(cl) {}
+
+  virtual void do_nmethod(nmethod* nm) {
+    ZNMethod::nmethod_oops_do(nm, _cl);
+  }
+};
+
+void ZNMethod::oops_do_begin() {
+  ZNMethodTable::nmethods_do_begin();
+}
+
+void ZNMethod::oops_do_end() {
+  ZNMethodTable::nmethods_do_end();
+}
+
+void ZNMethod::oops_do(OopClosure* cl) {
+  ZNMethodToOopsDoClosure nmethod_cl(cl);
+  ZNMethodTable::nmethods_do(&nmethod_cl);
+}
+
+class ZNMethodUnlinkClosure : public NMethodClosure {
+private:
+  bool          _unloading_occurred;
+  volatile bool _failed;
+
+  void set_failed() {
+    Atomic::store(true, &_failed);
+  }
+
+public:
+  ZNMethodUnlinkClosure(bool unloading_occurred) :
+      _unloading_occurred(unloading_occurred),
+      _failed(false) {}
+
+  virtual void do_nmethod(nmethod* nm) {
+    if (failed()) {
+      return;
+    }
+
+    if (!nm->is_alive()) {
+      return;
+    }
+
+    ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
+
+    if (nm->is_unloading()) {
+      // Unlinking of the dependencies must happen before the
+      // handshake separating unlink and purge.
+      nm->flush_dependencies(false /* delete_immediately */);
+
+      // We don't need to take the lock when unlinking nmethods from
+      // the Method, because it is only concurrently unlinked by
+      // the entry barrier, which acquires the per nmethod lock.
+      nm->unlink_from_method(false /* acquire_lock */);
+      return;
+    }
+
+    // Heal oops and disarm
+    ZNMethodOopClosure cl;
+    ZNMethod::nmethod_oops_do(nm, &cl);
+    ZNMethod::disarm_nmethod(nm);
+
+    // Clear compiled ICs and exception caches
+    if (!nm->unload_nmethod_caches(_unloading_occurred)) {
+      set_failed();
+    }
+  }
+
+  bool failed() const {
+    return Atomic::load(&_failed);
+  }
+};
+
+class ZNMethodUnlinkTask : public ZTask {
+private:
+  ZNMethodUnlinkClosure _cl;
+  ICRefillVerifier*     _verifier;
+
+public:
+  ZNMethodUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) :
+      ZTask("ZNMethodUnlinkTask"),
+      _cl(unloading_occurred),
+      _verifier(verifier) {
+    ZNMethodTable::nmethods_do_begin();
+  }
+
+  ~ZNMethodUnlinkTask() {
+    ZNMethodTable::nmethods_do_end();
+  }
+
+  virtual void work() {
+    ICRefillVerifierMark mark(_verifier);
+    ZNMethodTable::nmethods_do(&_cl);
+  }
+
+  bool success() const {
+    return !_cl.failed();
+  }
+};
+
+void ZNMethod::unlink(ZWorkers* workers, bool unloading_occurred) {
+  for (;;) {
+    ICRefillVerifier verifier;
+
+    {
+      ZNMethodUnlinkTask task(unloading_occurred, &verifier);
+      workers->run_concurrent(&task);
+      if (task.success()) {
+        return;
+      }
+    }
+
+    // Cleaning failed because we ran out of transitional IC stubs,
+    // so we have to refill and try again. Refilling requires taking
+    // a safepoint, so we temporarily leave the suspendible thread set.
+    SuspendibleThreadSetLeaver sts;
+    InlineCacheBuffer::refill_ic_stubs();
+  }
+}
+
+class ZNMethodPurgeClosure : public NMethodClosure {
+public:
+  virtual void do_nmethod(nmethod* nm) {
+    if (nm->is_alive() && nm->is_unloading()) {
+      nm->make_unloaded();
+    }
+  }
+};
+
+class ZNMethodPurgeTask : public ZTask {
+private:
+  ZNMethodPurgeClosure _cl;
+
+public:
+  ZNMethodPurgeTask() :
+      ZTask("ZNMethodPurgeTask"),
+      _cl() {
+    ZNMethodTable::nmethods_do_begin();
+  }
+
+  ~ZNMethodPurgeTask() {
+    ZNMethodTable::nmethods_do_end();
+  }
+
+  virtual void work() {
+    ZNMethodTable::nmethods_do(&_cl);
+  }
+};
+
+void ZNMethod::purge(ZWorkers* workers) {
+  ZNMethodPurgeTask task;
+  workers->run_concurrent(&task);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethod.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZNMETHOD_HPP
+#define SHARE_GC_Z_ZNMETHOD_HPP
+
+#include "memory/allocation.hpp"
+
+class nmethod;
+class OopClosure;
+class ZReentrantLock;
+class ZWorkers;
+
+class ZNMethod : public AllStatic {
+private:
+  static void attach_gc_data(nmethod* nm);
+
+  static void log_register(const nmethod* nm);
+  static void log_unregister(const nmethod* nm);
+
+public:
+  static void register_nmethod(nmethod* nm);
+  static void unregister_nmethod(nmethod* nm);
+  static void flush_nmethod(nmethod* nm);
+
+  static void disarm_nmethod(nmethod* nm);
+
+  static void nmethod_oops_do(nmethod* nm, OopClosure* cl);
+
+  static void oops_do_begin();
+  static void oops_do_end();
+  static void oops_do(OopClosure* cl);
+
+  static ZReentrantLock* lock_for_nmethod(nmethod* nm);
+
+  static void unlink(ZWorkers* workers, bool unloading_occurred);
+  static void purge(ZWorkers* workers);
+};
+
+#endif // SHARE_GC_Z_ZNMETHOD_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodAllocator.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zArray.inline.hpp"
+#include "gc/z/zNMethodAllocator.hpp"
+#include "memory/allocation.hpp"
+
+ZArray<void*> ZNMethodAllocator::_deferred_frees;
+bool          ZNMethodAllocator::_defer_frees(false);
+
+void ZNMethodAllocator::immediate_free(void* data) {
+  FREE_C_HEAP_ARRAY(uint8_t, data);
+}
+
+void ZNMethodAllocator::deferred_free(void* data) {
+  _deferred_frees.add(data);
+}
+
+void* ZNMethodAllocator::allocate(size_t size) {
+  return NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
+}
+
+void ZNMethodAllocator::free(void* data) {
+  if (data == NULL) {
+    return;
+  }
+
+  if (_defer_frees) {
+    deferred_free(data);
+  } else {
+    immediate_free(data);
+  }
+}
+
+void ZNMethodAllocator::activate_deferred_frees() {
+  assert(_deferred_frees.is_empty(), "precondition");
+  _defer_frees = true;
+}
+
+void ZNMethodAllocator::deactivate_and_process_deferred_frees() {
+  _defer_frees = false;
+
+  ZArrayIterator<void*> iter(&_deferred_frees);
+  for (void* data; iter.next(&data);) {
+    immediate_free(data);
+  }
+  _deferred_frees.clear();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodAllocator.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
+#define SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
+
+#include "memory/allocation.hpp"
+#include "gc/z/zArray.hpp"
+
+class ZNMethodAllocator : public AllStatic {
+private:
+  static ZArray<void*> _deferred_frees;
+  static bool          _defer_frees;
+
+  static void immediate_free(void* data);
+  static void deferred_free(void* data);
+
+public:
+  static void* allocate(size_t size);
+  static void free(void* data);
+
+  static void activate_deferred_frees();
+  static void deactivate_and_process_deferred_frees();
+};
+
+#endif // SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodData.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zLock.inline.hpp"
+#include "gc/z/zNMethodData.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/growableArray.hpp"
+
+size_t ZNMethodDataOops::header_size() {
+  const size_t size = sizeof(ZNMethodDataOops);
+  assert(is_aligned(size, sizeof(oop*)), "Header misaligned");
+  return size;
+}
+
+ZNMethodDataOops* ZNMethodDataOops::create(const GrowableArray<oop*>& immediates, bool has_non_immediates) {
+  // Allocate memory for the ZNMethodDataOops object
+  // plus the immediate oop* array that follows right after.
+  const size_t size = ZNMethodDataOops::header_size() + (sizeof(oop*) * immediates.length());
+  void* const mem = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
+  return ::new (mem) ZNMethodDataOops(immediates, has_non_immediates);
+}
+
+void ZNMethodDataOops::destroy(ZNMethodDataOops* oops) {
+  FREE_C_HEAP_ARRAY(uint8_t, oops);
+}
+
+ZNMethodDataOops::ZNMethodDataOops(const GrowableArray<oop*>& immediates, bool has_non_immediates) :
+    _nimmediates(immediates.length()),
+    _has_non_immediates(has_non_immediates) {
+  // Save all immediate oops
+  for (size_t i = 0; i < _nimmediates; i++) {
+    immediates_begin()[i] = immediates.at(i);
+  }
+}
+
+size_t ZNMethodDataOops::immediates_count() const {
+  return _nimmediates;
+}
+
+oop** ZNMethodDataOops::immediates_begin() const {
+  // The immediate oop* array starts immediately after this object
+  return (oop**)((uintptr_t)this + header_size());
+}
+
+oop** ZNMethodDataOops::immediates_end() const {
+  return immediates_begin() + immediates_count();
+}
+
+bool ZNMethodDataOops::has_non_immediates() const {
+  return _has_non_immediates;
+}
+
+ZNMethodData::ZNMethodData() :
+    _lock(),
+    _oops(NULL) {}
+
+ZNMethodData::~ZNMethodData() {
+  ZNMethodDataOops::destroy(_oops);
+}
+
+ZReentrantLock* ZNMethodData::lock() {
+  return &_lock;
+}
+
+ZNMethodDataOops* ZNMethodData::oops() const {
+  return OrderAccess::load_acquire(&_oops);
+}
+
+ZNMethodDataOops* ZNMethodData::swap_oops(ZNMethodDataOops* new_oops) {
+  ZLocker<ZReentrantLock> locker(&_lock);
+  ZNMethodDataOops* const old_oops = _oops;
+  _oops = new_oops;
+  return old_oops;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodData.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "gc/z/zLock.hpp"
+#include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#ifndef SHARE_GC_Z_ZNMETHODDATA_HPP
+#define SHARE_GC_Z_ZNMETHODDATA_HPP
+
+class nmethod;
+template <typename T> class GrowableArray;
+
+class ZNMethodDataOops {
+private:
+  const size_t _nimmediates;
+  bool         _has_non_immediates;
+
+  static size_t header_size();
+
+  ZNMethodDataOops(const GrowableArray<oop*>& immediates, bool has_non_immediates);
+
+public:
+  static ZNMethodDataOops* create(const GrowableArray<oop*>& immediates, bool has_non_immediates);
+  static void destroy(ZNMethodDataOops* oops);
+
+  size_t immediates_count() const;
+  oop** immediates_begin() const;
+  oop** immediates_end() const;
+
+  bool has_non_immediates() const;
+};
+
+class ZNMethodData : public CHeapObj<mtGC> {
+private:
+  ZReentrantLock             _lock;
+  ZNMethodDataOops* volatile _oops;
+
+public:
+  ZNMethodData();
+  ~ZNMethodData();
+
+  ZReentrantLock* lock();
+
+  ZNMethodDataOops* oops() const;
+  ZNMethodDataOops* swap_oops(ZNMethodDataOops* oops);
+};
+
+#endif // SHARE_GC_Z_ZNMETHODDATA_HPP
--- a/src/hotspot/share/gc/z/zNMethodTable.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTable.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,205 +27,38 @@
 #include "code/icBuffer.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/barrierSetNMethod.hpp"
-#include "gc/z/zArray.inline.hpp"
 #include "gc/z/zGlobals.hpp"
 #include "gc/z/zHash.inline.hpp"
 #include "gc/z/zLock.inline.hpp"
+#include "gc/z/zNMethodAllocator.hpp"
+#include "gc/z/zNMethodData.hpp"
 #include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNMethodTableEntry.hpp"
+#include "gc/z/zNMethodTableIteration.hpp"
 #include "gc/z/zOopClosures.inline.hpp"
 #include "gc/z/zTask.hpp"
 #include "gc/z/zWorkers.hpp"
 #include "logging/log.hpp"
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
+#include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/orderAccess.hpp"
-#include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 
-class ZNMethodDataImmediateOops {
-private:
-  const size_t _nimmediate_oops;
-
-  static size_t header_size();
-
-  ZNMethodDataImmediateOops(const GrowableArray<oop*>& immediate_oops);
-
-public:
-  static ZNMethodDataImmediateOops* create(const GrowableArray<oop*>& immediate_oops);
-  static void destroy(ZNMethodDataImmediateOops* data_immediate_oops);
-
-  size_t immediate_oops_count() const;
-  oop** immediate_oops_begin() const;
-  oop** immediate_oops_end() const;
-};
-
-size_t ZNMethodDataImmediateOops::header_size() {
-  const size_t size = sizeof(ZNMethodDataImmediateOops);
-  assert(is_aligned(size, sizeof(oop*)), "Header misaligned");
-  return size;
-}
-
-ZNMethodDataImmediateOops* ZNMethodDataImmediateOops::create(const GrowableArray<oop*>& immediate_oops) {
-  // Allocate memory for the ZNMethodDataImmediateOops object
-  // plus the immediate oop* array that follows right after.
-  const size_t size = ZNMethodDataImmediateOops::header_size() + (sizeof(oop*) * immediate_oops.length());
-  void* const data_immediate_oops = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
-  return ::new (data_immediate_oops) ZNMethodDataImmediateOops(immediate_oops);
-}
-
-void ZNMethodDataImmediateOops::destroy(ZNMethodDataImmediateOops* data_immediate_oops) {
-  ZNMethodTable::safe_delete(data_immediate_oops);
-}
-
-ZNMethodDataImmediateOops::ZNMethodDataImmediateOops(const GrowableArray<oop*>& immediate_oops) :
-    _nimmediate_oops(immediate_oops.length()) {
-  // Save all immediate oops
-  for (size_t i = 0; i < _nimmediate_oops; i++) {
-    immediate_oops_begin()[i] = immediate_oops.at(i);
-  }
-}
-
-size_t ZNMethodDataImmediateOops::immediate_oops_count() const {
-  return _nimmediate_oops;
-}
-
-oop** ZNMethodDataImmediateOops::immediate_oops_begin() const {
-  // The immediate oop* array starts immediately after this object
-  return (oop**)((uintptr_t)this + header_size());
-}
-
-oop** ZNMethodDataImmediateOops::immediate_oops_end() const {
-  return immediate_oops_begin() + immediate_oops_count();
-}
-
-class ZNMethodData {
-private:
-  ZReentrantLock                      _lock;
-  ZNMethodDataImmediateOops* volatile _immediate_oops;
-
-  ZNMethodData(nmethod* nm);
-
-public:
-  static ZNMethodData* create(nmethod* nm);
-  static void destroy(ZNMethodData* data);
-
-  ZReentrantLock* lock();
-
-  ZNMethodDataImmediateOops* immediate_oops() const;
-  ZNMethodDataImmediateOops* swap_immediate_oops(const GrowableArray<oop*>& immediate_oops);
-};
-
-ZNMethodData* ZNMethodData::create(nmethod* nm) {
-  void* const method = NEW_C_HEAP_ARRAY(uint8_t, sizeof(ZNMethodData), mtGC);
-  return ::new (method) ZNMethodData(nm);
-}
-
-void ZNMethodData::destroy(ZNMethodData* data) {
-  ZNMethodDataImmediateOops::destroy(data->immediate_oops());
-  ZNMethodTable::safe_delete(data);
-}
-
-ZNMethodData::ZNMethodData(nmethod* nm) :
-    _lock(),
-    _immediate_oops(NULL) {}
-
-ZReentrantLock* ZNMethodData::lock() {
-  return &_lock;
-}
-
-ZNMethodDataImmediateOops* ZNMethodData::immediate_oops() const {
-  return OrderAccess::load_acquire(&_immediate_oops);
-}
-
-ZNMethodDataImmediateOops* ZNMethodData::swap_immediate_oops(const GrowableArray<oop*>& immediate_oops) {
-  ZNMethodDataImmediateOops* const data_immediate_oops =
-    immediate_oops.is_empty() ? NULL : ZNMethodDataImmediateOops::create(immediate_oops);
-  return Atomic::xchg(data_immediate_oops, &_immediate_oops);
-}
-
-static ZNMethodData* gc_data(const nmethod* nm) {
-  return nm->gc_data<ZNMethodData>();
-}
-
-static void set_gc_data(nmethod* nm, ZNMethodData* data) {
-  return nm->set_gc_data<ZNMethodData>(data);
-}
-
 ZNMethodTableEntry* ZNMethodTable::_table = NULL;
 size_t ZNMethodTable::_size = 0;
-ZLock ZNMethodTable::_iter_lock;
-ZNMethodTableEntry* ZNMethodTable::_iter_table = NULL;
-size_t ZNMethodTable::_iter_table_size = 0;
-ZArray<void*> ZNMethodTable::_iter_deferred_deletes;
 size_t ZNMethodTable::_nregistered = 0;
 size_t ZNMethodTable::_nunregistered = 0;
-volatile size_t ZNMethodTable::_claimed = 0;
+ZNMethodTableIteration ZNMethodTable::_iteration;
 
-void ZNMethodTable::safe_delete(void* data) {
-  if (data == NULL) {
-    return;
-  }
-
-  ZLocker<ZLock> locker(&_iter_lock);
-  if (_iter_table != NULL) {
-    // Iteration in progress, defer delete
-    _iter_deferred_deletes.add(data);
-  } else {
-    // Iteration not in progress, delete now
-    FREE_C_HEAP_ARRAY(uint8_t, data);
-  }
+ZNMethodTableEntry* ZNMethodTable::create(size_t size) {
+  void* const mem = ZNMethodAllocator::allocate(size * sizeof(ZNMethodTableEntry));
+  return ::new (mem) ZNMethodTableEntry[size];
 }
 
-ZNMethodTableEntry ZNMethodTable::create_entry(nmethod* nm) {
-  GrowableArray<oop*> immediate_oops;
-  bool non_immediate_oops = false;
-
-  // Find all oops relocations
-  RelocIterator iter(nm);
-  while (iter.next()) {
-    if (iter.type() != relocInfo::oop_type) {
-      // Not an oop
-      continue;
-    }
-
-    oop_Relocation* r = iter.oop_reloc();
-
-    if (!r->oop_is_immediate()) {
-      // Non-immediate oop found
-      non_immediate_oops = true;
-      continue;
-    }
-
-    if (r->oop_value() != NULL) {
-      // Non-NULL immediate oop found. NULL oops can safely be
-      // ignored since the method will be re-registered if they
-      // are later patched to be non-NULL.
-      immediate_oops.push(r->oop_addr());
-    }
-  }
-
-  // Attach GC data to nmethod
-  ZNMethodData* data = gc_data(nm);
-  if (data == NULL) {
-    data = ZNMethodData::create(nm);
-    set_gc_data(nm, data);
-  }
-
-  // Attach immediate oops in GC data
-  ZNMethodDataImmediateOops* const old_data_immediate_oops = data->swap_immediate_oops(immediate_oops);
-  ZNMethodDataImmediateOops::destroy(old_data_immediate_oops);
-
-  // Create entry
-  return ZNMethodTableEntry(nm, non_immediate_oops, !immediate_oops.is_empty());
-}
-
-ZReentrantLock* ZNMethodTable::lock_for_nmethod(nmethod* nm) {
-  ZNMethodData* const data = gc_data(nm);
-  if (data == NULL) {
-    return NULL;
-  }
-  return data->lock();
+void ZNMethodTable::destroy(ZNMethodTableEntry* table) {
+  ZNMethodAllocator::free(table);
 }
 
 size_t ZNMethodTable::first_index(const nmethod* nm, size_t size) {
@@ -241,8 +74,8 @@
   return (prev_index + 1) & mask;
 }
 
-bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry) {
-  const nmethod* const nm = entry.method();
+bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) {
+  const ZNMethodTableEntry entry(nm);
   size_t index = first_index(nm, size);
 
   for (;;) {
@@ -265,11 +98,6 @@
 }
 
 void ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) {
-  if (size == 0) {
-    // Table is empty
-    return;
-  }
-
   size_t index = first_index(nm, size);
 
   for (;;) {
@@ -279,10 +107,6 @@
     if (table_entry.registered() && table_entry.method() == nm) {
       // Remove entry
       table[index] = ZNMethodTableEntry(true /* unregistered */);
-
-      // Destroy GC data
-      ZNMethodData::destroy(gc_data(nm));
-      set_gc_data(nm, NULL);
       return;
     }
 
@@ -291,7 +115,8 @@
 }
 
 void ZNMethodTable::rebuild(size_t new_size) {
-  ZLocker<ZLock> locker(&_iter_lock);
+  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
+
   assert(is_power_of_2(new_size), "Invalid size");
 
   log_debug(gc, nmethod)("Rebuilding NMethod Table: "
@@ -303,20 +128,18 @@
                          _nunregistered, percent_of(_nunregistered, _size), 0.0);
 
   // Allocate new table
-  ZNMethodTableEntry* const new_table = new ZNMethodTableEntry[new_size];
+  ZNMethodTableEntry* const new_table = ZNMethodTable::create(new_size);
 
   // Transfer all registered entries
   for (size_t i = 0; i < _size; i++) {
     const ZNMethodTableEntry entry = _table[i];
     if (entry.registered()) {
-      register_entry(new_table, new_size, entry);
+      register_entry(new_table, new_size, entry.method());
     }
   }
 
-  if (_iter_table != _table) {
-    // Delete old table
-    delete [] _table;
-  }
+  // Free old table
+  ZNMethodTable::destroy(_table);
 
   // Install new table
   _table = new_table;
@@ -353,61 +176,6 @@
   }
 }
 
-void ZNMethodTable::log_register(const nmethod* nm, ZNMethodTableEntry entry) {
-  LogTarget(Trace, gc, nmethod) log;
-  if (!log.is_enabled()) {
-    return;
-  }
-
-  log.print("Register NMethod: %s.%s (" PTR_FORMAT "), "
-            "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s",
-            nm->method()->method_holder()->external_name(),
-            nm->method()->name()->as_C_string(),
-            p2i(nm),
-            nm->compiler_name(),
-            nm->oops_count() - 1,
-            entry.immediate_oops() ? gc_data(nm)->immediate_oops()->immediate_oops_count() : 0,
-            entry.non_immediate_oops() ? "Yes" : "No");
-
-  LogTarget(Trace, gc, nmethod, oops) log_oops;
-  if (!log_oops.is_enabled()) {
-    return;
-  }
-
-  // Print nmethod oops table
-  oop* const begin = nm->oops_begin();
-  oop* const end = nm->oops_end();
-  for (oop* p = begin; p < end; p++) {
-    log_oops.print("           Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)",
-                   (p - begin), p2i(*p), (*p)->klass()->external_name());
-  }
-
-  if (entry.immediate_oops()) {
-    // Print nmethod immediate oops
-    const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops();
-    if (nmi != NULL) {
-      oop** const begin = nmi->immediate_oops_begin();
-      oop** const end = nmi->immediate_oops_end();
-      for (oop** p = begin; p < end; p++) {
-        log_oops.print("  ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)",
-                       (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name());
-      }
-    }
-  }
-}
-
-void ZNMethodTable::log_unregister(const nmethod* nm) {
-  LogTarget(Debug, gc, nmethod) log;
-  if (!log.is_enabled()) {
-    return;
-  }
-
-  log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")",
-            nm->method()->method_holder()->external_name(),
-            nm->method()->name()->as_C_string(),
-            p2i(nm));
-}
-
 size_t ZNMethodTable::registered_nmethods() {
   return _nregistered;
 }
@@ -418,48 +186,29 @@
 
 void ZNMethodTable::register_nmethod(nmethod* nm) {
   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
-  ResourceMark rm;
 
   // Grow/Shrink/Prune table if needed
   rebuild_if_needed();
 
-  // Create entry
-  const ZNMethodTableEntry entry = create_entry(nm);
-
-  log_register(nm, entry);
-
   // Insert new entry
-  if (register_entry(_table, _size, entry)) {
+  if (register_entry(_table, _size, nm)) {
     // New entry registered. When register_entry() instead returns
     // false the nmethod was already in the table so we do not want
     // to increase number of registered entries in that case.
     _nregistered++;
   }
-
-  // Disarm nmethod entry barrier
-  disarm_nmethod(nm);
 }
 
-void ZNMethodTable::sweeper_wait_for_iteration() {
-  // The sweeper must wait for any ongoing iteration to complete
-  // before it can unregister an nmethod.
-  if (!Thread::current()->is_Code_cache_sweeper_thread()) {
-    return;
-  }
+void ZNMethodTable::wait_until_iteration_done() {
+  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 
-  while (_iter_table != NULL) {
-    MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    os::naked_short_sleep(1);
+  while (_iteration.in_progress()) {
+    CodeCache_lock->wait(Monitor::_no_safepoint_check_flag);
   }
 }
 
 void ZNMethodTable::unregister_nmethod(nmethod* nm) {
   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
-  ResourceMark rm;
-
-  sweeper_wait_for_iteration();
-
-  log_unregister(nm);
 
   // Remove entry
   unregister_entry(_table, _size, nm);
@@ -467,248 +216,29 @@
   _nregistered--;
 }
 
-void ZNMethodTable::disarm_nmethod(nmethod* nm) {
-  BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
-  if (bs != NULL) {
-    bs->disarm(nm);
-  }
+void ZNMethodTable::nmethods_do_begin() {
+  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+
+  // Make sure we don't free data while iterating
+  ZNMethodAllocator::activate_deferred_frees();
+
+  // Prepare iteration
+  _iteration.nmethods_do_begin(_table, _size);
 }
 
-void ZNMethodTable::nmethod_entries_do_begin() {
+void ZNMethodTable::nmethods_do_end() {
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-  ZLocker<ZLock> locker(&_iter_lock);
 
-  // Prepare iteration
-  _iter_table = _table;
-  _iter_table_size = _size;
-  _claimed = 0;
-  assert(_iter_deferred_deletes.is_empty(), "Should be emtpy");
+  // Finish iteration
+  _iteration.nmethods_do_end();
+
+  // Process deferred frees
+  ZNMethodAllocator::deactivate_and_process_deferred_frees();
+
+  // Notify iteration done
+  CodeCache_lock->notify_all();
 }
 
-void ZNMethodTable::nmethod_entries_do_end() {
-  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-  ZLocker<ZLock> locker(&_iter_lock);
-
-  // Finish iteration
-  if (_iter_table != _table) {
-    delete [] _iter_table;
-  }
-  _iter_table = NULL;
-  assert(_claimed >= _iter_table_size, "Failed to claim all table entries");
-
-  // Process deferred deletes
-  ZArrayIterator<void*> iter(&_iter_deferred_deletes);
-  for (void* data; iter.next(&data);) {
-    FREE_C_HEAP_ARRAY(uint8_t, data);
-  }
-  _iter_deferred_deletes.clear();
+void ZNMethodTable::nmethods_do(NMethodClosure* cl) {
+  _iteration.nmethods_do(cl);
 }
-
-void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) {
-  nmethod* const nm = entry.method();
-
-  // Process oops table
-  oop* const begin = nm->oops_begin();
-  oop* const end = nm->oops_end();
-  for (oop* p = begin; p < end; p++) {
-    if (*p != Universe::non_oop_word()) {
-      cl->do_oop(p);
-    }
-  }
-
-  // Process immediate oops
-  if (entry.immediate_oops()) {
-    const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops();
-    if (nmi != NULL) {
-      oop** const begin = nmi->immediate_oops_begin();
-      oop** const end = nmi->immediate_oops_end();
-      for (oop** p = begin; p < end; p++) {
-        if (**p != Universe::non_oop_word()) {
-          cl->do_oop(*p);
-        }
-      }
-    }
-  }
-
-  // Process non-immediate oops
-  if (entry.non_immediate_oops()) {
-    nmethod* const nm = entry.method();
-    nm->fix_oop_relocations();
-  }
-}
-
-class ZNMethodTableEntryToOopsDo : public ZNMethodTableEntryClosure {
-private:
-  OopClosure* _cl;
-
-public:
-  ZNMethodTableEntryToOopsDo(OopClosure* cl) :
-      _cl(cl) {}
-
-  void do_nmethod_entry(ZNMethodTableEntry entry) {
-    ZNMethodTable::entry_oops_do(entry, _cl);
-  }
-};
-
-void ZNMethodTable::oops_do(OopClosure* cl) {
-  ZNMethodTableEntryToOopsDo entry_cl(cl);
-  nmethod_entries_do(&entry_cl);
-}
-
-void ZNMethodTable::nmethod_entries_do(ZNMethodTableEntryClosure* cl) {
-  for (;;) {
-    // Claim table partition. Each partition is currently sized to span
-    // two cache lines. This number is just a guess, but seems to work well.
-    const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry);
-    const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _iter_table_size);
-    const size_t partition_end = MIN2(partition_start + partition_size, _iter_table_size);
-    if (partition_start == partition_end) {
-      // End of table
-      break;
-    }
-
-    // Process table partition
-    for (size_t i = partition_start; i < partition_end; i++) {
-      const ZNMethodTableEntry entry = _iter_table[i];
-      if (entry.registered()) {
-        cl->do_nmethod_entry(entry);
-      }
-    }
-  }
-}
-
-class ZNMethodTableUnlinkClosure : public ZNMethodTableEntryClosure {
-private:
-  bool          _unloading_occurred;
-  volatile bool _failed;
-
-  void set_failed() {
-    Atomic::store(true, &_failed);
-  }
-
-public:
-  ZNMethodTableUnlinkClosure(bool unloading_occurred) :
-      _unloading_occurred(unloading_occurred),
-      _failed(false) {}
-
-  virtual void do_nmethod_entry(ZNMethodTableEntry entry) {
-    if (failed()) {
-      return;
-    }
-
-    nmethod* const nm = entry.method();
-    if (!nm->is_alive()) {
-      return;
-    }
-
-    ZLocker<ZReentrantLock> locker(ZNMethodTable::lock_for_nmethod(nm));
-
-    if (nm->is_unloading()) {
-      // Unlinking of the dependencies must happen before the
-      // handshake separating unlink and purge.
-      nm->flush_dependencies(false /* delete_immediately */);
-
-      // We don't need to take the lock when unlinking nmethods from
-      // the Method, because it is only concurrently unlinked by
-      // the entry barrier, which acquires the per nmethod lock.
-      nm->unlink_from_method(false /* acquire_lock */);
-      return;
-    }
-
-    // Heal oops and disarm
-    ZNMethodOopClosure cl;
-    ZNMethodTable::entry_oops_do(entry, &cl);
-    ZNMethodTable::disarm_nmethod(nm);
-
-    // Clear compiled ICs and exception caches
-    if (!nm->unload_nmethod_caches(_unloading_occurred)) {
-      set_failed();
-    }
-  }
-
-  bool failed() const {
-    return Atomic::load(&_failed);
-  }
-};
-
-class ZNMethodTableUnlinkTask : public ZTask {
-private:
-  ZNMethodTableUnlinkClosure _cl;
-  ICRefillVerifier*          _verifier;
-
-public:
-  ZNMethodTableUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) :
-      ZTask("ZNMethodTableUnlinkTask"),
-      _cl(unloading_occurred),
-      _verifier(verifier) {
-    ZNMethodTable::nmethod_entries_do_begin();
-  }
-
-  ~ZNMethodTableUnlinkTask() {
-    ZNMethodTable::nmethod_entries_do_end();
-  }
-
-  virtual void work() {
-    ICRefillVerifierMark mark(_verifier);
-    ZNMethodTable::nmethod_entries_do(&_cl);
-  }
-
-  bool success() const {
-    return !_cl.failed();
-  }
-};
-
-void ZNMethodTable::unlink(ZWorkers* workers, bool unloading_occurred) {
-  for (;;) {
-    ICRefillVerifier verifier;
-
-    {
-      ZNMethodTableUnlinkTask task(unloading_occurred, &verifier);
-      workers->run_concurrent(&task);
-      if (task.success()) {
-        return;
-      }
-    }
-
-    // Cleaning failed because we ran out of transitional IC stubs,
-    // so we have to refill and try again. Refilling requires taking
-    // a safepoint, so we temporarily leave the suspendible thread set.
-    SuspendibleThreadSetLeaver sts;
-    InlineCacheBuffer::refill_ic_stubs();
-  }
-}
-
-class ZNMethodTablePurgeClosure : public ZNMethodTableEntryClosure {
-public:
-  virtual void do_nmethod_entry(ZNMethodTableEntry entry) {
-    nmethod* const nm = entry.method();
-    if (nm->is_alive() && nm->is_unloading()) {
-      nm->make_unloaded();
-    }
-  }
-};
-
-class ZNMethodTablePurgeTask : public ZTask {
-private:
-  ZNMethodTablePurgeClosure _cl;
-
-public:
-  ZNMethodTablePurgeTask() :
-      ZTask("ZNMethodTablePurgeTask"),
-      _cl() {
-    ZNMethodTable::nmethod_entries_do_begin();
-  }
-
-  ~ZNMethodTablePurgeTask() {
-    ZNMethodTable::nmethod_entries_do_end();
-  }
-
-  virtual void work() {
-    ZNMethodTable::nmethod_entries_do(&_cl);
-  }
-};
-
-void ZNMethodTable::purge(ZWorkers* workers) {
-  ZNMethodTablePurgeTask task;
-  workers->run_concurrent(&task);
-}
--- a/src/hotspot/share/gc/z/zNMethodTable.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTable.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,66 +24,46 @@
 #ifndef SHARE_GC_Z_ZNMETHODTABLE_HPP
 #define SHARE_GC_Z_ZNMETHODTABLE_HPP
 
-#include "gc/z/zArray.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zLock.hpp"
-#include "gc/z/zNMethodTableEntry.hpp"
+#include "gc/z/zNMethodTableIteration.hpp"
 #include "memory/allocation.hpp"
 
+class nmethod;
+class NMethodClosure;
+class ZNMethodTableEntry;
 class ZWorkers;
 
-class ZNMethodTableEntryClosure {
-public:
-  virtual void do_nmethod_entry(ZNMethodTableEntry entry) = 0;
-};
-
 class ZNMethodTable : public AllStatic {
 private:
-  static ZNMethodTableEntry* _table;
-  static size_t              _size;
-  static ZLock               _iter_lock;
-  static ZNMethodTableEntry* _iter_table;
-  static size_t              _iter_table_size;
-  static ZArray<void*>       _iter_deferred_deletes;
-  static size_t              _nregistered;
-  static size_t              _nunregistered;
-  static volatile size_t     _claimed ATTRIBUTE_ALIGNED(ZCacheLineSize);
+  static ZNMethodTableEntry*    _table;
+  static size_t                 _size;
+  static size_t                 _nregistered;
+  static size_t                 _nunregistered;
+  static ZNMethodTableIteration _iteration;
 
-  static ZNMethodTableEntry create_entry(nmethod* nm);
+  static ZNMethodTableEntry* create(size_t size);
+  static void destroy(ZNMethodTableEntry* table);
 
   static size_t first_index(const nmethod* nm, size_t size);
   static size_t next_index(size_t prev_index, size_t size);
 
-  static void sweeper_wait_for_iteration();
-
-  static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry);
+  static bool register_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm);
   static void unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm);
 
   static void rebuild(size_t new_size);
   static void rebuild_if_needed();
 
-  static void log_register(const nmethod* nm, ZNMethodTableEntry entry);
-  static void log_unregister(const nmethod* nm);
-
 public:
-  static void safe_delete(void* data);
-
   static size_t registered_nmethods();
   static size_t unregistered_nmethods();
 
   static void register_nmethod(nmethod* nm);
   static void unregister_nmethod(nmethod* nm);
-  static void disarm_nmethod(nmethod* nm);
 
-  static ZReentrantLock* lock_for_nmethod(nmethod* nm);
+  static void wait_until_iteration_done();
 
-  static void oops_do(OopClosure* cl);
-
-  static void entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl);
-
-  static void nmethod_entries_do_begin();
-  static void nmethod_entries_do_end();
-  static void nmethod_entries_do(ZNMethodTableEntryClosure* cl);
+  static void nmethods_do_begin();
+  static void nmethods_do_end();
+  static void nmethods_do(NMethodClosure* cl);
 
   static void unlink(ZWorkers* workers, bool unloading_occurred);
   static void purge(ZWorkers* workers);
--- a/src/hotspot/share/gc/z/zNMethodTableEntry.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTableEntry.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -32,16 +32,16 @@
 // --------------------------
 //
 //   6
-//   3                                                                  3 2 1 0
-//  +--------------------------------------------------------------------+-+-+-+
-//  |11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111|1|1|1|
-//  +--------------------------------------------------------------------+-+-+-+
-//  |                                                                    | | |
-//  |                               2-2 Non-immediate Oops Flag (1-bits) * | |
-//  |                                                                      | |
-//  |                        1-1 Immediate Oops/Unregistered Flag (1-bits) * |
-//  |                                                                        |
-//  |                                           0-0 Registered Flag (1-bits) *
+//   3                                                                   2 1 0
+//  +---------------------------------------------------------------------+-+-+
+//  |11111111 11111111 11111111 11111111 11111111 11111111 11111111 111111|1|1|
+//  +---------------------------------------------------------------------+-+-+
+//  |                                                                     | |
+//  |                                                                     | |
+//  |                                                                     | |
+//  |                                      1-1 Unregistered Flag (1-bits) * |
+//  |                                                                       |
+//  |                                          0-0 Registered Flag (1-bits) *
 //  |
 //  * 63-3 NMethod Address (61-bits)
 //
@@ -52,22 +52,20 @@
 private:
   typedef ZBitField<uint64_t, bool,     0,  1>    field_registered;
   typedef ZBitField<uint64_t, bool,     1,  1>    field_unregistered;
-  typedef ZBitField<uint64_t, bool,     1,  1>    field_immediate_oops;
-  typedef ZBitField<uint64_t, bool,     2,  1>    field_non_immediate_oops;
-  typedef ZBitField<uint64_t, nmethod*, 3, 61, 3> field_method;
+  typedef ZBitField<uint64_t, nmethod*, 2, 62, 2> field_method;
 
   uint64_t _entry;
 
 public:
   explicit ZNMethodTableEntry(bool unregistered = false) :
-      _entry(field_unregistered::encode(unregistered) |
-             field_registered::encode(false)) {}
+      _entry(field_registered::encode(false) |
+             field_unregistered::encode(unregistered) |
+             field_method::encode(NULL)) {}
 
-  ZNMethodTableEntry(nmethod* method, bool non_immediate_oops, bool immediate_oops) :
-      _entry(field_method::encode(method) |
-             field_non_immediate_oops::encode(non_immediate_oops) |
-             field_immediate_oops::encode(immediate_oops) |
-             field_registered::encode(true)) {}
+  explicit ZNMethodTableEntry(nmethod* method) :
+      _entry(field_registered::encode(true) |
+             field_unregistered::encode(false) |
+             field_method::encode(method)) {}
 
   bool registered() const {
     return field_registered::decode(_entry);
@@ -77,14 +75,6 @@
     return field_unregistered::decode(_entry);
   }
 
-  bool immediate_oops() const {
-    return field_immediate_oops::decode(_entry);
-  }
-
-  bool non_immediate_oops() const {
-    return field_non_immediate_oops::decode(_entry);
-  }
-
   nmethod* method() const {
     return field_method::decode(_entry);
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodTableIteration.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zNMethodTableEntry.hpp"
+#include "gc/z/zNMethodTableIteration.hpp"
+#include "memory/iterator.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+ZNMethodTableIteration::ZNMethodTableIteration() :
+    _table(NULL),
+    _size(0),
+    _claimed(0) {}
+
+bool ZNMethodTableIteration::in_progress() const {
+  return _table != NULL;
+}
+
+void ZNMethodTableIteration::nmethods_do_begin(ZNMethodTableEntry* table, size_t size) {
+  assert(!in_progress(), "precondition");
+
+  _table = table;
+  _size = size;
+  _claimed = 0;
+}
+
+void ZNMethodTableIteration::nmethods_do_end() {
+  assert(_claimed >= _size, "Failed to claim all table entries");
+
+  // Finish iteration
+  _table = NULL;
+}
+
+void ZNMethodTableIteration::nmethods_do(NMethodClosure* cl) {
+  for (;;) {
+    // Claim table partition. Each partition is currently sized to span
+    // two cache lines. This number is just a guess, but seems to work well.
+    const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry);
+    const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _size);
+    const size_t partition_end = MIN2(partition_start + partition_size, _size);
+    if (partition_start == partition_end) {
+      // End of table
+      break;
+    }
+
+    // Process table partition
+    for (size_t i = partition_start; i < partition_end; i++) {
+      const ZNMethodTableEntry entry = _table[i];
+      if (entry.registered()) {
+        cl->do_nmethod(entry.method());
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodTableIteration.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP
+#define SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP
+
+#include "gc/z/zGlobals.hpp"
+
+class NMethodClosure;
+class ZNMethodTableEntry;
+
+class ZNMethodTableIteration {
+private:
+  ZNMethodTableEntry* _table;
+  size_t              _size;
+  volatile size_t     _claimed ATTRIBUTE_ALIGNED(ZCacheLineSize);
+
+public:
+  ZNMethodTableIteration();
+
+  bool in_progress() const;
+
+  void nmethods_do_begin(ZNMethodTableEntry* table, size_t size);
+  void nmethods_do_end();
+  void nmethods_do(NMethodClosure* cl);
+};
+
+#endif // SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -33,7 +33,7 @@
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/z/zBarrierSetNMethod.hpp"
 #include "gc/z/zGlobals.hpp"
-#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNMethod.hpp"
 #include "gc/z/zOopClosures.inline.hpp"
 #include "gc/z/zRootsIterator.hpp"
 #include "gc/z/zStat.hpp"
@@ -184,7 +184,7 @@
   if (ClassUnloading) {
     nmethod::oops_do_marking_prologue();
   } else {
-    ZNMethodTable::nmethod_entries_do_begin();
+    ZNMethod::oops_do_begin();
   }
 }
 
@@ -194,7 +194,7 @@
   if (ClassUnloading) {
     nmethod::oops_do_marking_epilogue();
   } else {
-    ZNMethodTable::nmethod_entries_do_end();
+    ZNMethod::oops_do_end();
   }
   JvmtiExport::gc_epilogue();
 
@@ -242,7 +242,7 @@
 
 void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) {
   ZStatTimer timer(ZSubPhasePauseRootsCodeCache);
-  ZNMethodTable::oops_do(cl);
+  ZNMethod::oops_do(cl);
 }
 
 void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl, bool visit_jvmti_weak_export) {
--- a/src/hotspot/share/gc/z/zUnload.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/gc/z/zUnload.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -30,7 +30,7 @@
 #include "gc/shared/gcBehaviours.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/z/zLock.inline.hpp"
-#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNMethod.hpp"
 #include "gc/z/zOopClosures.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zUnload.hpp"
@@ -65,43 +65,30 @@
 };
 
 class ZIsUnloadingBehaviour : public IsUnloadingBehaviour {
-private:
-  bool is_unloading(nmethod* nm) const {
+public:
+  virtual bool is_unloading(CompiledMethod* method) const {
+    nmethod* const nm = method->as_nmethod();
+    ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
+    ZLocker<ZReentrantLock> locker(lock);
     ZIsUnloadingOopClosure cl;
     nm->oops_do(&cl, true /* allow_zombie */);
     return cl.is_unloading();
   }
-
-public:
-  virtual bool is_unloading(CompiledMethod* method) const {
-    nmethod* const nm = method->as_nmethod();
-    ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm);
-    if (lock == NULL) {
-      return is_unloading(nm);
-    } else {
-      ZLocker<ZReentrantLock> locker(lock);
-      return is_unloading(nm);
-    }
-  }
 };
 
 class ZCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour {
 public:
   virtual bool lock(CompiledMethod* method) {
     nmethod* const nm = method->as_nmethod();
-    ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm);
-    if (lock != NULL) {
-      lock->lock();
-    }
+    ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
+    lock->lock();
     return true;
   }
 
   virtual void unlock(CompiledMethod* method) {
     nmethod* const nm = method->as_nmethod();
-    ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm);
-    if (lock != NULL) {
-      lock->unlock();
-    }
+    ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
+    lock->unlock();
   }
 
   virtual bool is_safe(CompiledMethod* method) {
@@ -110,8 +97,8 @@
     }
 
     nmethod* const nm = method->as_nmethod();
-    ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm);
-    return lock == NULL || lock->is_owned();
+    ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
+    return lock->is_owned();
   }
 };
 
@@ -149,7 +136,7 @@
 
   Klass::clean_weak_klass_links(unloading_occurred);
 
-  ZNMethodTable::unlink(_workers, unloading_occurred);
+  ZNMethod::unlink(_workers, unloading_occurred);
 
   DependencyContext::cleaning_end();
 }
@@ -157,7 +144,7 @@
 void ZUnload::purge() {
   {
     SuspendibleThreadSetJoiner sts;
-    ZNMethodTable::purge(_workers);
+    ZNMethod::purge(_workers);
   }
 
   ClassLoaderDataGraph::purge();
--- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -114,7 +114,7 @@
 NO_TRANSITION_END
 
 NO_TRANSITION(void, jfr_set_file_notification(JNIEnv* env, jobject jvm, jlong threshold))
-  JfrChunkRotation::set_threshold((intptr_t)threshold);
+  JfrChunkRotation::set_threshold(threshold);
 NO_TRANSITION_END
 
 NO_TRANSITION(void, jfr_set_sample_threads(JNIEnv* env, jobject jvm, jboolean sampleThreads))
--- a/src/hotspot/share/jfr/metadata/metadata.xml	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/metadata/metadata.xml	Thu Feb 28 22:05:33 2019 +0100
@@ -533,12 +533,6 @@
     <Field type="int" name="iterations" label="Iterations" description="Number of state check iterations" />
   </Event>
 
-  <Event name="SafepointWaitBlocked" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Wait Blocked" description="Safepointing begin waiting on running threads to block"
-    thread="true">
-    <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
-    <Field type="int" name="runningThreadCount" label="Running Threads" description="The number running of threads wait for safe point" />
-  </Event>
-
   <Event name="SafepointCleanup" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup" description="Safepointing begin running cleanup tasks"
     thread="true">
     <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -44,13 +44,13 @@
   }
 }
 
-static void write_checkpoint_header(u1* pos, jlong size, jlong time, bool flushpoint, juint type_count) {
+static void write_checkpoint_header(u1* pos, int64_t size, jlong time, bool flushpoint, u4 type_count) {
   assert(pos != NULL, "invariant");
   JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry));
   be_writer.write(size);
   be_writer.write(time);
   be_writer.write(JfrTicks::now().value() - time);
-  be_writer.write(flushpoint ? (juint)1 : (juint)0);
+  be_writer.write(flushpoint ? (u4)1 : (u4)0);
   be_writer.write(type_count);
   assert(be_writer.is_valid(), "invariant");
 }
@@ -71,7 +71,7 @@
   assert(this->is_valid(), "invariant");
   assert(count() > 0, "invariant");
   assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant");
-  const jlong size = this->current_offset();
+  const int64_t size = this->current_offset();
   assert(size + this->start_pos() == this->current_pos(), "invariant");
   write_checkpoint_header(const_cast<u1*>(this->start_pos()), size, _time, is_flushpoint(), count());
   release();
@@ -85,11 +85,11 @@
   return _flushpoint;
 }
 
-juint JfrCheckpointWriter::count() const {
+u4 JfrCheckpointWriter::count() const {
   return _count;
 }
 
-void JfrCheckpointWriter::set_count(juint count) {
+void JfrCheckpointWriter::set_count(u4 count) {
   _count = count;
 }
 
@@ -111,7 +111,7 @@
 }
 
 void JfrCheckpointWriter::write_key(u8 key) {
-  write<u8>(key);
+  write(key);
 }
 
 void JfrCheckpointWriter::increment() {
@@ -119,10 +119,10 @@
 }
 
 void JfrCheckpointWriter::write_count(u4 nof_entries) {
-  write<u4>((u4)nof_entries);
+  write(nof_entries);
 }
 
-void JfrCheckpointWriter::write_count(u4 nof_entries, jlong offset) {
+void JfrCheckpointWriter::write_count(u4 nof_entries, int64_t offset) {
   write_padded_at_offset(nof_entries, offset);
 }
 
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -49,21 +49,21 @@
 typedef EventWriterHost<BigEndianEncoder, CompressedIntegerEncoder, JfrTransactionalCheckpointWriter> JfrCheckpointWriterBase;
 
 struct JfrCheckpointContext {
-  jlong offset;
-  juint count;
+  int64_t offset;
+  u4 count;
 };
 
 class JfrCheckpointWriter : public JfrCheckpointWriterBase {
   friend class JfrSerializerRegistration;
  private:
   JfrTicks _time;
-  jlong _offset;
-  juint _count;
+  int64_t _offset;
+  u4 _count;
   bool _flushpoint;
   bool _header;
 
-  juint count() const;
-  void set_count(juint count);
+  u4 count() const;
+  void set_count(u4 count);
   void increment();
   void set_flushpoint(bool flushpoint);
   bool is_flushpoint() const;
@@ -75,7 +75,7 @@
   ~JfrCheckpointWriter();
   void write_type(JfrTypeId type_id);
   void write_count(u4 nof_entries);
-  void write_count(u4 nof_entries, jlong offset);
+  void write_count(u4 nof_entries, int64_t offset);
   void write_key(u8 key);
   const JfrCheckpointContext context() const;
   void set_context(const JfrCheckpointContext ctx);
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -65,7 +65,7 @@
  private:
   JfrCheckpointWriter& _writer;
   JfrCheckpointContext _ctx;
-  const intptr_t _count_position;
+  const int64_t _count_position;
   Thread* const _curthread;
   u4 _count;
 
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -35,7 +35,7 @@
   WriterImpl _impl;
   JfrCheckpointWriter* _writer;
   JfrCheckpointContext _ctx;
-  jlong _count_offset;
+  int64_t _count_offset;
   int _count;
   bool _skip_header;
  public:
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -29,7 +29,7 @@
 #include "runtime/handles.inline.hpp"
 
 static jobject chunk_monitor = NULL;
-static intptr_t threshold = 0;
+static int64_t threshold = 0;
 static bool rotate = false;
 
 static jobject install_chunk_monitor(Thread* thread) {
@@ -62,7 +62,6 @@
     // already in progress
     return;
   }
-  assert(!rotate, "invariant");
   if (writer.size_written() > threshold) {
     rotate = true;
     notify();
@@ -77,6 +76,6 @@
   rotate = false;
 }
 
-void JfrChunkRotation::set_threshold(intptr_t bytes) {
+void JfrChunkRotation::set_threshold(int64_t bytes) {
   threshold = bytes;
 }
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -36,7 +36,7 @@
 class JfrChunkRotation : AllStatic {
  public:
   static void evaluate(const JfrChunkWriter& writer);
-  static void set_threshold(intptr_t bytes);
+  static void set_threshold(int64_t bytes);
   static bool should_rotate();
   static void on_rotation();
 };
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkState.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkState.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -53,19 +53,19 @@
   set_previous_checkpoint_offset(0);
 }
 
-void JfrChunkState::set_previous_checkpoint_offset(jlong offset) {
+void JfrChunkState::set_previous_checkpoint_offset(int64_t offset) {
   _previous_checkpoint_offset = offset;
 }
 
-jlong JfrChunkState::previous_checkpoint_offset() const {
+int64_t JfrChunkState::previous_checkpoint_offset() const {
   return _previous_checkpoint_offset;
 }
 
-jlong JfrChunkState::previous_start_ticks() const {
+int64_t JfrChunkState::previous_start_ticks() const {
   return _previous_start_ticks;
 }
 
-jlong JfrChunkState::previous_start_nanos() const {
+int64_t JfrChunkState::previous_start_nanos() const {
   return _previous_start_nanos;
 }
 
@@ -92,7 +92,7 @@
   save_current_and_update_start_ticks();
 }
 
-jlong JfrChunkState::last_chunk_duration() const {
+int64_t JfrChunkState::last_chunk_duration() const {
   return _start_nanos - _previous_start_nanos;
 }
 
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkState.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkState.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -25,7 +25,6 @@
 #ifndef SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKSTATE_HPP
 #define SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKSTATE_HPP
 
-#include "jni.h"
 #include "jfr/utilities/jfrAllocation.hpp"
 #include "jfr/utilities/jfrTypes.hpp"
 
@@ -33,11 +32,11 @@
   friend class JfrChunkWriter;
  private:
   char* _path;
-  jlong _start_ticks;
-  jlong _start_nanos;
-  jlong _previous_start_ticks;
-  jlong _previous_start_nanos;
-  jlong _previous_checkpoint_offset;
+  int64_t _start_ticks;
+  int64_t _start_nanos;
+  int64_t _previous_start_ticks;
+  int64_t _previous_start_nanos;
+  int64_t _previous_checkpoint_offset;
 
   void update_start_ticks();
   void update_start_nanos();
@@ -47,11 +46,11 @@
   JfrChunkState();
   ~JfrChunkState();
   void reset();
-  jlong previous_checkpoint_offset() const;
-  void set_previous_checkpoint_offset(jlong offset);
-  jlong previous_start_ticks() const;
-  jlong previous_start_nanos() const;
-  jlong last_chunk_duration() const;
+  int64_t previous_checkpoint_offset() const;
+  void set_previous_checkpoint_offset(int64_t offset);
+  int64_t previous_start_ticks() const;
+  int64_t previous_start_nanos() const;
+  int64_t last_chunk_duration() const;
   void update_time_to_now();
   void set_path(const char* path);
   const char* path() const;
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -32,9 +32,8 @@
 #include "runtime/os.hpp"
 #include "runtime/os.inline.hpp"
 
-const u2 JFR_VERSION_MAJOR = 2;
-const u2 JFR_VERSION_MINOR = 0;
-
+static const u2 JFR_VERSION_MAJOR = 2;
+static const u2 JFR_VERSION_MINOR = 0;
 static const size_t MAGIC_LEN = 4;
 static const size_t FILEHEADER_SLOT_SIZE = 8;
 static const size_t CHUNK_SIZE_OFFSET = 8;
@@ -79,14 +78,14 @@
   return is_open;
 }
 
-size_t JfrChunkWriter::close(intptr_t metadata_offset) {
+size_t JfrChunkWriter::close(int64_t metadata_offset) {
   write_header(metadata_offset);
   this->flush();
   this->close_fd();
-  return size_written();
+  return (size_t)size_written();
 }
 
-void JfrChunkWriter::write_header(intptr_t metadata_offset) {
+void JfrChunkWriter::write_header(int64_t metadata_offset) {
   assert(this->is_valid(), "invariant");
   // Chunk size
   this->write_be_at_offset(size_written(), CHUNK_SIZE_OFFSET);
@@ -106,15 +105,15 @@
   _chunkstate->set_path(chunk_path);
 }
 
-intptr_t JfrChunkWriter::size_written() const {
+int64_t JfrChunkWriter::size_written() const {
   return this->is_valid() ? this->current_offset() : 0;
 }
 
-intptr_t JfrChunkWriter::previous_checkpoint_offset() const {
+int64_t JfrChunkWriter::previous_checkpoint_offset() const {
   return _chunkstate->previous_checkpoint_offset();
 }
 
-void JfrChunkWriter::set_previous_checkpoint_offset(intptr_t offset) {
+void JfrChunkWriter::set_previous_checkpoint_offset(int64_t offset) {
   _chunkstate->set_previous_checkpoint_offset(offset);
 }
 
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -41,16 +41,16 @@
   JfrChunkState* _chunkstate;
 
   bool open();
-  size_t close(intptr_t metadata_offset);
-  void write_header(intptr_t metadata_offset);
+  size_t close(int64_t metadata_offset);
+  void write_header(int64_t metadata_offset);
   void set_chunk_path(const char* chunk_path);
 
  public:
   JfrChunkWriter();
   bool initialize();
-  intptr_t size_written() const;
-  intptr_t previous_checkpoint_offset() const;
-  void set_previous_checkpoint_offset(intptr_t offset);
+  int64_t size_written() const;
+  int64_t previous_checkpoint_offset() const;
+  void set_previous_checkpoint_offset(int64_t offset);
   void time_stamp_chunk_now();
 };
 
--- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -147,10 +147,10 @@
   iso8601_to_date_time(buffer);
 }
 
-static jlong file_size(fio_fd fd) {
+static int64_t file_size(fio_fd fd) {
   assert(fd != invalid_fd, "invariant");
-  const jlong current_offset = os::current_file_offset(fd);
-  const jlong size = os::lseek(fd, 0, SEEK_END);
+  const int64_t current_offset = os::current_file_offset(fd);
+  const int64_t size = os::lseek(fd, 0, SEEK_END);
   os::seek_to_file_offset(fd, current_offset);
   return size;
 }
@@ -218,7 +218,7 @@
   if (invalid_fd == entry_fd) {
     return NULL;
   }
-  const jlong entry_size = file_size(entry_fd);
+  const int64_t entry_size = file_size(entry_fd);
   os::close(entry_fd);
   if (0 == entry_size) {
     return NULL;
@@ -260,6 +260,7 @@
   }
 }
 #endif
+
 bool RepositoryIterator::has_next() const {
   return (_files != NULL && _iterator < _files->length());
 }
@@ -275,21 +276,27 @@
   if (file_copy_block == NULL) {
     return;
   }
- jlong bytes_written_total = 0;
+ int64_t bytes_written_total = 0;
   while (iterator.has_next()) {
     fio_fd current_fd = invalid_fd;
     const char* const fqn = iterator.next();
     if (fqn != NULL) {
       current_fd = open_existing(fqn);
       if (current_fd != invalid_fd) {
-        const jlong current_filesize = file_size(current_fd);
+        const int64_t current_filesize = file_size(current_fd);
         assert(current_filesize > 0, "invariant");
-        jlong bytes_read = 0;
-        jlong bytes_written = 0;
+        int64_t bytes_read = 0;
+        int64_t bytes_written = 0;
         while (bytes_read < current_filesize) {
-          bytes_read += (jlong)os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read);
-          assert(bytes_read - bytes_written <= (jlong)size_of_file_copy_block, "invariant");
-          bytes_written += (jlong)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written);
+          const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read);
+          if (-1 == read_result) {
+            log_info(jfr) ( // For user, should not be "jfr, system"
+              "Unable to recover JFR data");
+            break;
+          }
+          bytes_read += (int64_t)read_result;
+          assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant");
+          bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written);
           assert(bytes_read == bytes_written, "invariant");
         }
         os::close(current_fd);
@@ -468,6 +475,6 @@
   return _chunkwriter->open();
 }
 
-size_t JfrRepository::close_chunk(jlong metadata_offset) {
+size_t JfrRepository::close_chunk(int64_t metadata_offset) {
   return _chunkwriter->close(metadata_offset);
 }
--- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -55,7 +55,7 @@
   bool set_path(const char* path);
   void set_chunk_path(const char* path);
   bool open_chunk(bool vm_error = false);
-  size_t close_chunk(jlong metadata_offset);
+  size_t close_chunk(int64_t metadata_offset);
   void on_vm_error();
   static void notify_on_new_chunk_path();
   static JfrChunkWriter& chunkwriter();
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -130,18 +130,18 @@
   bool not_acquired() const { return !_acquired; }
 };
 
-static intptr_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
-  const intptr_t prev_cp_offset = cw.previous_checkpoint_offset();
-  const intptr_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset();
+static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
+  const int64_t prev_cp_offset = cw.previous_checkpoint_offset();
+  const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset();
   cw.reserve(sizeof(u4));
   cw.write<u8>(EVENT_CHECKPOINT);
   cw.write(JfrTicks::now());
-  cw.write<jlong>((jlong)0);
+  cw.write((int64_t)0);
   cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta
   cw.write<bool>(false); // flushpoint
-  cw.write<u4>((u4)1); // nof types in this checkpoint
-  cw.write<u8>(type_id);
-  const intptr_t number_of_elements_offset = cw.current_offset();
+  cw.write((u4)1); // nof types in this checkpoint
+  cw.write(type_id);
+  const int64_t number_of_elements_offset = cw.current_offset();
   cw.reserve(sizeof(u4));
   return number_of_elements_offset;
 }
@@ -161,8 +161,8 @@
   }
   bool process() {
     // current_cp_offset is also offset for the event size header field
-    const intptr_t current_cp_offset = _cw.current_offset();
-    const intptr_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id);
+    const int64_t current_cp_offset = _cw.current_offset();
+    const int64_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id);
     // invocation
     _content_functor.process();
     const u4 number_of_elements = (u4)_content_functor.processed();
@@ -468,9 +468,9 @@
   JfrMetadataEvent::lock();
 }
 
-static jlong write_metadata_event(JfrChunkWriter& chunkwriter) {
+static int64_t write_metadata_event(JfrChunkWriter& chunkwriter) {
   assert(chunkwriter.is_valid(), "invariant");
-  const jlong metadata_offset = chunkwriter.current_offset();
+  const int64_t metadata_offset = chunkwriter.current_offset();
   JfrMetadataEvent::write(chunkwriter, metadata_offset);
   return metadata_offset;
 }
--- a/src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -49,7 +49,7 @@
 inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_write(void) {
   assert(this->is_acquired(),
     "state corruption, calling end with writer with non-acquired state!");
-  return this->is_valid() ? this->used_offset() : 0;
+  return this->is_valid() ? (intptr_t)this->used_offset() : 0;
 }
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
--- a/src/hotspot/share/jfr/writers/jfrPosition.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrPosition.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -48,8 +48,8 @@
 
  public:
   size_t available_size() const;
-  intptr_t used_offset() const;
-  intptr_t current_offset() const;
+  int64_t used_offset() const;
+  int64_t current_offset() const;
   size_t used_size() const;
   void reset();
 };
--- a/src/hotspot/share/jfr/writers/jfrPosition.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrPosition.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -80,12 +80,12 @@
 }
 
 template <typename AP>
-inline intptr_t Position<AP>::used_offset() const {
+inline int64_t Position<AP>::used_offset() const {
   return _current_pos - _start_pos;
 }
 
 template <typename AP>
-inline intptr_t Position<AP>::current_offset() const {
+inline int64_t Position<AP>::current_offset() const {
   return this->used_offset();
 }
 
--- a/src/hotspot/share/jfr/writers/jfrStreamWriterHost.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrStreamWriterHost.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -33,9 +33,9 @@
  public:
   typedef typename Adapter::StorageType StorageType;
  private:
-  intptr_t _stream_pos;
+  int64_t _stream_pos;
   fio_fd _fd;
-  intptr_t current_stream_position() const;
+  int64_t current_stream_position() const;
 
  protected:
   StreamWriterHost(StorageType* storage, Thread* thread);
@@ -47,8 +47,8 @@
   bool has_valid_fd() const;
 
  public:
-  intptr_t current_offset() const;
-  void seek(intptr_t offset);
+  int64_t current_offset() const;
+  void seek(int64_t offset);
   void flush();
   void write_unbuffered(const void* src, size_t len);
   bool is_valid() const;
--- a/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -44,7 +44,7 @@
 }
 
 template <typename Adapter, typename AP>
-inline intptr_t StreamWriterHost<Adapter, AP>::current_stream_position() const {
+inline int64_t StreamWriterHost<Adapter, AP>::current_stream_position() const {
   return this->used_offset() + _stream_pos;
 }
 
@@ -73,7 +73,7 @@
 inline void StreamWriterHost<Adapter, AP>::flush(size_t size) {
   assert(size > 0, "invariant");
   assert(this->is_valid(), "invariant");
-  _stream_pos += os::write(_fd, this->start_pos(), (int)size);
+  _stream_pos += os::write(_fd, this->start_pos(), (unsigned int)size);
   StorageHost<Adapter, AP>::reset();
   assert(0 == this->used_offset(), "invariant");
 }
@@ -84,12 +84,12 @@
 }
 
 template <typename Adapter, typename AP>
-inline intptr_t StreamWriterHost<Adapter, AP>::current_offset() const {
+inline int64_t StreamWriterHost<Adapter, AP>::current_offset() const {
   return current_stream_position();
 }
 
 template <typename Adapter, typename AP>
-void StreamWriterHost<Adapter, AP>::seek(intptr_t offset) {
+void StreamWriterHost<Adapter, AP>::seek(int64_t offset) {
   this->flush();
   assert(0 == this->used_offset(), "can only seek from beginning");
   _stream_pos = os::seek_to_file_offset(_fd, offset);
@@ -110,7 +110,7 @@
   this->flush();
   assert(0 == this->used_offset(), "can only seek from beginning");
   while (len > 0) {
-    const int n = MIN2<int>((int)len, INT_MAX);
+    const unsigned int n = MIN2((unsigned int)len, (unsigned int)INT_MAX);
     _stream_pos += os::write(_fd, buf, n);
     len -= n;
   }
--- a/src/hotspot/share/jfr/writers/jfrWriterHost.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrWriterHost.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -91,12 +91,12 @@
   void bytes(const void* buf, size_t len);
   void write_utf8_u2_len(const char* value);
   template <typename T>
-  void write_padded_at_offset(T value, intptr_t offset);
+  void write_padded_at_offset(T value, int64_t offset);
   template <typename T>
-  void write_at_offset(T value, intptr_t offset);
+  void write_at_offset(T value, int64_t offset);
   template <typename T>
-  void write_be_at_offset(T value, intptr_t offset);
-  intptr_t reserve(size_t size);
+  void write_be_at_offset(T value, int64_t offset);
+  int64_t reserve(size_t size);
 };
 
 #endif // SHARE_JFR_WRITERS_JFRWRITERHOST_HPP
--- a/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -196,7 +196,7 @@
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(double value) {
-  be_write(*(uintptr_t*)&(value));
+  be_write(*(u8*)&(value));
 }
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
@@ -317,9 +317,9 @@
 }
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
-inline intptr_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) {
+inline int64_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) {
   if (ensure_size(size) != NULL) {
-    intptr_t reserved_offset = this->current_offset();
+    const int64_t reserved_offset = this->current_offset();
     this->set_current_pos(size);
     return reserved_offset;
   }
@@ -329,9 +329,9 @@
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
 template <typename T>
-inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, intptr_t offset) {
+inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, int64_t offset) {
   if (this->is_valid()) {
-    const intptr_t current = this->current_offset();
+    const int64_t current = this->current_offset();
     this->seek(offset);
     write_padded(value);
     this->seek(current); // restore
@@ -340,9 +340,9 @@
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
 template <typename T>
-inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, intptr_t offset) {
+inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, int64_t offset) {
   if (this->is_valid()) {
-    const intptr_t current = this->current_offset();
+    const int64_t current = this->current_offset();
     this->seek(offset);
     write(value);
     this->seek(current); // restore
@@ -351,9 +351,9 @@
 
 template <typename BE, typename IE, typename WriterPolicyImpl>
 template <typename T>
-inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, intptr_t offset) {
+inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, int64_t offset) {
   if (this->is_valid()) {
-    const intptr_t current = this->current_offset();
+    const int64_t current = this->current_offset();
     this->seek(offset);
     be_write(value);
     this->seek(current); // restore
--- a/src/hotspot/share/memory/filemap.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/java.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/memTracker.hpp"
@@ -501,6 +502,16 @@
   }
 
   _validating_shared_path_table = false;
+
+#if INCLUDE_JVMTI
+  if (_classpath_entries_for_jvmti != NULL) {
+    os::free(_classpath_entries_for_jvmti);
+  }
+  size_t sz = sizeof(ClassPathEntry*) *  _shared_path_table_size;
+  _classpath_entries_for_jvmti = (ClassPathEntry**)os::malloc(sz, mtClass);
+  memset(_classpath_entries_for_jvmti, 0, sz);
+#endif
+
   return true;
 }
 
@@ -550,7 +561,7 @@
 // Read the FileMapInfo information from the file.
 bool FileMapInfo::open_for_read() {
   _full_path = Arguments::GetSharedArchivePath();
-  int fd = open(_full_path, O_RDONLY | O_BINARY, 0);
+  int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
     if (errno == ENOENT) {
       // Not locating the shared archive is ok.
@@ -585,7 +596,7 @@
   // Use remove() to delete the existing file because, on Unix, this will
   // allow processes that have it open continued access to the file.
   remove(_full_path);
-  int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
+  int fd = os::open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
   if (fd < 0) {
     fail_stop("Unable to create shared archive file %s: (%s).", _full_path,
               os::strerror(errno));
@@ -1440,3 +1451,57 @@
     fail_stop("%s", msg);
   }
 }
+
+#if INCLUDE_JVMTI
+ClassPathEntry** FileMapInfo::_classpath_entries_for_jvmti = NULL;
+
+ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) {
+  ClassPathEntry* ent = _classpath_entries_for_jvmti[i];
+  if (ent == NULL) {
+    if (i == 0) {
+      ent = ClassLoader:: get_jrt_entry();
+      assert(ent != NULL, "must be");
+    } else {
+      SharedClassPathEntry* scpe = shared_path(i);
+      assert(scpe->is_jar(), "must be"); // other types of scpe will not produce archived classes
+
+      const char* path = scpe->name();
+      struct stat st;
+      if (os::stat(path, &st) != 0) {
+        char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); ;
+        jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
+        THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL);
+      } else {
+        ent = ClassLoader::create_class_path_entry(path, &st, /*throw_exception=*/true, false, CHECK_NULL);
+      }
+    }
+
+    MutexLocker mu(CDSClassFileStream_lock, THREAD);
+    if (_classpath_entries_for_jvmti[i] == NULL) {
+      _classpath_entries_for_jvmti[i] = ent;
+    } else {
+      // Another thread has beat me to creating this entry
+      delete ent;
+      ent = _classpath_entries_for_jvmti[i];
+    }
+  }
+
+  return ent;
+}
+
+ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, TRAPS) {
+  int path_index = ik->shared_classpath_index();
+  assert(path_index >= 0, "should be called for shared built-in classes only");
+  assert(path_index < (int)_shared_path_table_size, "sanity");
+
+  ClassPathEntry* cpe = get_classpath_entry_for_jvmti(path_index, CHECK_NULL);
+  assert(cpe != NULL, "must be");
+
+  Symbol* name = ik->name();
+  const char* const class_name = name->as_C_string();
+  const char* const file_name = ClassLoader::file_name_for_class_name(class_name,
+                                                                      name->utf8_length());
+  return cpe->open_stream(file_name, THREAD);
+}
+
+#endif
--- a/src/hotspot/share/memory/filemap.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/filemap.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -302,6 +302,10 @@
   bool validate_shared_path_table();
   static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
 
+#if INCLUDE_JVMTI
+  static ClassFileStream* open_stream_for_jvmti(InstanceKlass* ik, TRAPS);
+#endif
+
   static SharedClassPathEntry* shared_path(int index) {
     if (index < 0) {
       return NULL;
@@ -348,6 +352,11 @@
   }
 
   address decode_start_address(CDSFileMapRegion* spc, bool with_current_oop_encoding_mode);
+
+#if INCLUDE_JVMTI
+  static ClassPathEntry** _classpath_entries_for_jvmti;
+  static ClassPathEntry* get_classpath_entry_for_jvmti(int i, TRAPS);
+#endif
 };
 
 #endif // SHARE_MEMORY_FILEMAP_HPP
--- a/src/hotspot/share/memory/iterator.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/iterator.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -263,6 +263,11 @@
   virtual void do_code_blob(CodeBlob* cb);
 };
 
+class NMethodClosure : public Closure {
+ public:
+  virtual void do_nmethod(nmethod* n) = 0;
+};
+
 // MonitorClosure is used for iterating over monitors in the monitors cache
 
 class ObjectMonitor;
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -207,7 +207,7 @@
 };
 
 
-DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md"), _od_region("od");
+DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md");
 size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0;
 
 char* MetaspaceShared::misc_code_space_alloc(size_t num_bytes) {
@@ -598,23 +598,6 @@
   }
 }
 
-static void relocate_cached_class_file() {
-  for (int i = 0; i < _global_klass_objects->length(); i++) {
-    Klass* k = _global_klass_objects->at(i);
-    if (k->is_instance_klass()) {
-      InstanceKlass* ik = InstanceKlass::cast(k);
-      JvmtiCachedClassFileData* p = ik->get_archived_class_data();
-      if (p != NULL) {
-        int size = offset_of(JvmtiCachedClassFileData, data) + p->length;
-        JvmtiCachedClassFileData* q = (JvmtiCachedClassFileData*)_od_region.allocate(size);
-        q->length = p->length;
-        memcpy(q->data, p->data, p->length);
-        ik->set_archived_class_data(q);
-      }
-    }
-  }
-}
-
 // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
 // (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
 //
@@ -1438,15 +1421,11 @@
 
   char* vtbl_list = _md_region.top();
   MetaspaceShared::allocate_cpp_vtable_clones();
-  _md_region.pack(&_od_region);
+  _md_region.pack();
 
-  // Relocate the archived class file data into the od region
-  relocate_cached_class_file();
-  _od_region.pack();
-
-  // The 5 core spaces are allocated consecutively mc->rw->ro->md->od, so there total size
+  // The 4 core spaces are allocated consecutively mc->rw->ro->md, so there total size
   // is just the spaces between the two ends.
-  size_t core_spaces_size = _od_region.end() - _mc_region.base();
+  size_t core_spaces_size = _md_region.end() - _mc_region.base();
   assert(core_spaces_size == (size_t)align_up(core_spaces_size, Metaspace::reserve_alignment()),
          "should already be aligned");
 
@@ -1488,7 +1467,6 @@
     write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
     write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
     write_region(mapinfo, MetaspaceShared::md, &_md_region, /*read_only=*/false,/*allow_exec=*/false);
-    write_region(mapinfo, MetaspaceShared::od, &_od_region, /*read_only=*/true, /*allow_exec=*/false);
 
     _total_closed_archive_region_size = mapinfo->write_archive_heap_regions(
                                         _closed_archive_heap_regions,
@@ -1535,12 +1513,10 @@
   // Print statistics of all the regions
   const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
                                 _mc_region.reserved()  + _md_region.reserved() +
-                                _od_region.reserved()  +
                                 _total_closed_archive_region_size +
                                 _total_open_archive_region_size;
   const size_t total_bytes = _ro_region.used()  + _rw_region.used() +
                              _mc_region.used()  + _md_region.used() +
-                             _od_region.used()  +
                              _total_closed_archive_region_size +
                              _total_open_archive_region_size;
   const double total_u_perc = percent_of(total_bytes, total_reserved);
@@ -1549,7 +1525,6 @@
   _rw_region.print(total_reserved);
   _ro_region.print(total_reserved);
   _md_region.print(total_reserved);
-  _od_region.print(total_reserved);
   print_heap_region_stats(_closed_archive_heap_regions, "ca", total_reserved);
   print_heap_region_stats(_open_archive_heap_regions, "oa", total_reserved);
 
@@ -1931,33 +1906,30 @@
   char* rw_base = NULL; char* rw_top;
   char* mc_base = NULL; char* mc_top;
   char* md_base = NULL; char* md_top;
-  char* od_base = NULL; char* od_top;
 
   // Map each shared region
   if ((mc_base = mapinfo->map_region(mc, &mc_top)) != NULL &&
       (rw_base = mapinfo->map_region(rw, &rw_top)) != NULL &&
       (ro_base = mapinfo->map_region(ro, &ro_top)) != NULL &&
       (md_base = mapinfo->map_region(md, &md_top)) != NULL &&
-      (od_base = mapinfo->map_region(od, &od_top)) != NULL &&
       (image_alignment == (size_t)os::vm_allocation_granularity()) &&
       mapinfo->validate_shared_path_table()) {
     // Success -- set up MetaspaceObj::_shared_metaspace_{base,top} for
     // fast checking in MetaspaceShared::is_in_shared_metaspace() and
     // MetaspaceObj::is_shared().
     //
-    // We require that mc->rw->ro->md->od to be laid out consecutively, with no
+    // We require that mc->rw->ro->md to be laid out consecutively, with no
     // gaps between them. That way, we can ensure that the OS won't be able to
     // allocate any new memory spaces inside _shared_metaspace_{base,top}, which
     // would mess up the simple comparision in MetaspaceShared::is_in_shared_metaspace().
-    assert(mc_base < ro_base && mc_base < rw_base && mc_base < md_base && mc_base < od_base, "must be");
-    assert(od_top  > ro_top  && od_top  > rw_top  && od_top  > md_top  && od_top  > mc_top , "must be");
+    assert(mc_base < ro_base && mc_base < rw_base && mc_base < md_base, "must be");
+    assert(md_top  > ro_top  && md_top  > rw_top  && md_top  > mc_top , "must be");
     assert(mc_top == rw_base, "must be");
     assert(rw_top == ro_base, "must be");
     assert(ro_top == md_base, "must be");
-    assert(md_top == od_base, "must be");
 
     _core_spaces_size = mapinfo->core_spaces_size();
-    MetaspaceObj::set_shared_metaspace_range((void*)mc_base, (void*)od_top);
+    MetaspaceObj::set_shared_metaspace_range((void*)mc_base, (void*)md_top);
     return true;
   } else {
     // If there was a failure in mapping any of the spaces, unmap the ones
@@ -1966,7 +1938,6 @@
     if (rw_base != NULL) mapinfo->unmap_region(rw);
     if (mc_base != NULL) mapinfo->unmap_region(mc);
     if (md_base != NULL) mapinfo->unmap_region(md);
-    if (od_base != NULL) mapinfo->unmap_region(od);
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
@@ -2049,7 +2020,6 @@
   _rw_region.print_out_of_space_msg(name, needed_bytes);
   _ro_region.print_out_of_space_msg(name, needed_bytes);
   _md_region.print_out_of_space_msg(name, needed_bytes);
-  _od_region.print_out_of_space_msg(name, needed_bytes);
 
   vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name),
                                 "Please reduce the number of shared classes.");
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -69,14 +69,10 @@
     ro = 2,  // read-only shared space in the heap
     md = 3,  // miscellaneous data for initializing tables, etc.
     num_core_spaces = 4, // number of non-string regions
-
-    // optional mapped spaces
-    // Currently it only contains class file data.
-    od = num_core_spaces,
-    num_non_heap_spaces = od + 1,
+    num_non_heap_spaces = 4,
 
     // mapped java heap regions
-    first_closed_archive_heap_region = od + 1,
+    first_closed_archive_heap_region = md + 1,
     max_closed_archive_heap_region = 2,
     last_closed_archive_heap_region = first_closed_archive_heap_region + max_closed_archive_heap_region - 1,
     first_open_archive_heap_region = last_closed_archive_heap_region + 1,
--- a/src/hotspot/share/memory/universe.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/universe.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -107,6 +107,7 @@
 LatestMethodCache* Universe::_finalizer_register_cache = NULL;
 LatestMethodCache* Universe::_loader_addClass_cache    = NULL;
 LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL;
+LatestMethodCache* Universe::_throw_no_such_method_error_cache = NULL;
 LatestMethodCache* Universe::_do_stack_walk_cache     = NULL;
 oop Universe::_out_of_memory_error_java_heap          = NULL;
 oop Universe::_out_of_memory_error_metaspace          = NULL;
@@ -230,6 +231,7 @@
   _finalizer_register_cache->metaspace_pointers_do(it);
   _loader_addClass_cache->metaspace_pointers_do(it);
   _throw_illegal_access_error_cache->metaspace_pointers_do(it);
+  _throw_no_such_method_error_cache->metaspace_pointers_do(it);
   _do_stack_walk_cache->metaspace_pointers_do(it);
 }
 
@@ -271,6 +273,7 @@
   _finalizer_register_cache->serialize(f);
   _loader_addClass_cache->serialize(f);
   _throw_illegal_access_error_cache->serialize(f);
+  _throw_no_such_method_error_cache->serialize(f);
   _do_stack_walk_cache->serialize(f);
 }
 
@@ -689,6 +692,7 @@
   Universe::_finalizer_register_cache = new LatestMethodCache();
   Universe::_loader_addClass_cache    = new LatestMethodCache();
   Universe::_throw_illegal_access_error_cache = new LatestMethodCache();
+  Universe::_throw_no_such_method_error_cache = new LatestMethodCache();
   Universe::_do_stack_walk_cache = new LatestMethodCache();
 
 #if INCLUDE_CDS
@@ -935,6 +939,11 @@
                           "throwIllegalAccessError",
                           vmSymbols::void_method_signature(), true, CHECK);
 
+  initialize_known_method(_throw_no_such_method_error_cache,
+                          SystemDictionary::internal_Unsafe_klass(),
+                          "throwNoSuchMethodError",
+                          vmSymbols::void_method_signature(), true, CHECK);
+
   // Set up method for registering loaded classes in class loader vector
   initialize_known_method(_loader_addClass_cache,
                           SystemDictionary::ClassLoader_klass(),
--- a/src/hotspot/share/memory/universe.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/memory/universe.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -138,6 +138,7 @@
   static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
   static LatestMethodCache* _loader_addClass_cache;    // method for registering loaded classes in class loader vector
   static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method
+  static LatestMethodCache* _throw_no_such_method_error_cache; // Unsafe.throwNoSuchMethodError() method
   static LatestMethodCache* _do_stack_walk_cache;      // method for stack walker callback
 
   // preallocated error objects (no backtrace)
@@ -322,6 +323,7 @@
   static Method*      loader_addClass_method()        { return _loader_addClass_cache->get_method(); }
 
   static Method*      throw_illegal_access_error()    { return _throw_illegal_access_error_cache->get_method(); }
+  static Method*      throw_no_such_method_error()    { return _throw_no_such_method_error_cache->get_method(); }
 
   static Method*      do_stack_walk_method()          { return _do_stack_walk_cache->get_method(); }
 
--- a/src/hotspot/share/oops/cpCache.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/cpCache.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -591,7 +591,7 @@
 
 // a constant pool cache entry should never contain old or obsolete methods
 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
-  Method* m = get_interesting_method_entry(NULL);
+  Method* m = get_interesting_method_entry();
   // return false if m refers to a non-deleted old or obsolete method
   if (m != NULL) {
     assert(m->is_valid() && m->is_method(), "m is a valid method");
@@ -601,7 +601,7 @@
   }
 }
 
-Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
+Method* ConstantPoolCacheEntry::get_interesting_method_entry() {
   if (!is_method_entry()) {
     // not a method entry so not interesting by default
     return NULL;
@@ -622,12 +622,9 @@
     }
   }
   assert(m != NULL && m->is_method(), "sanity check");
-  if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
-    // robustness for above sanity checks or method is not in
-    // the interesting class
+  if (m == NULL || !m->is_method()) {
     return NULL;
   }
-  // the method is in the interesting class so the entry is interesting
   return m;
 }
 #endif // INCLUDE_JVMTI
@@ -777,10 +774,10 @@
 // RedefineClasses() API support:
 // If any entry of this ConstantPoolCache points to any of
 // old_methods, replace it with the corresponding new_method.
-void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+void ConstantPoolCache::adjust_method_entries(bool * trace_name_printed) {
   for (int i = 0; i < length(); i++) {
     ConstantPoolCacheEntry* entry = entry_at(i);
-    Method* old_method = entry->get_interesting_method_entry(holder);
+    Method* old_method = entry->get_interesting_method_entry();
     if (old_method == NULL || !old_method->is_old()) {
       continue; // skip uninteresting entries
     }
@@ -789,11 +786,7 @@
       entry->initialize_entry(entry->constant_pool_index());
       continue;
     }
-    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
-
-    assert(new_method != NULL, "method_with_idnum() should not be NULL");
-    assert(old_method != new_method, "sanity check");
-
+    Method* new_method = old_method->get_new_method();
     entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed);
   }
 }
@@ -801,7 +794,7 @@
 // the constant pool cache should never contain old or obsolete methods
 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
   for (int i = 1; i < length(); i++) {
-    if (entry_at(i)->get_interesting_method_entry(NULL) != NULL &&
+    if (entry_at(i)->get_interesting_method_entry() != NULL &&
         !entry_at(i)->check_no_old_or_obsolete_entries()) {
       return false;
     }
@@ -811,7 +804,7 @@
 
 void ConstantPoolCache::dump_cache() {
   for (int i = 1; i < length(); i++) {
-    if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) {
+    if (entry_at(i)->get_interesting_method_entry() != NULL) {
       entry_at(i)->print(tty, i);
     }
   }
--- a/src/hotspot/share/oops/cpCache.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/cpCache.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -376,7 +376,7 @@
   void adjust_method_entry(Method* old_method, Method* new_method,
          bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
-  Method* get_interesting_method_entry(Klass* k);
+  Method* get_interesting_method_entry();
 #endif // INCLUDE_JVMTI
 
   // Debugging & Printing
@@ -496,7 +496,7 @@
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
-  void adjust_method_entries(InstanceKlass* holder, bool* trace_name_printed);
+  void adjust_method_entries(bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_cache();
 #endif // INCLUDE_JVMTI
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -2353,6 +2353,7 @@
 #if INCLUDE_JVMTI
   guarantee(_breakpoints == NULL, "must be");
   guarantee(_previous_versions == NULL, "must be");
+  _cached_class_file = NULL;
 #endif
 
   _init_thread = NULL;
@@ -2509,7 +2510,7 @@
   }
 
   // deallocate the cached class file
-  if (_cached_class_file != NULL && !MetaspaceShared::is_in_shared_metaspace(_cached_class_file)) {
+  if (_cached_class_file != NULL) {
     os::free(_cached_class_file);
     _cached_class_file = NULL;
   }
@@ -2916,22 +2917,18 @@
 // not yet in the vtable due to concurrent subclass define and superinterface
 // redefinition
 // Note: those in the vtable, should have been updated via adjust_method_entries
-void InstanceKlass::adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed) {
+void InstanceKlass::adjust_default_methods(bool* trace_name_printed) {
   // search the default_methods for uses of either obsolete or EMCP methods
   if (default_methods() != NULL) {
     for (int index = 0; index < default_methods()->length(); index ++) {
       Method* old_method = default_methods()->at(index);
-      if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+      if (old_method == NULL || !old_method->is_old()) {
         continue; // skip uninteresting entries
       }
       assert(!old_method->is_deleted(), "default methods may not be deleted");
-
-      Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
-
-      assert(new_method != NULL, "method_with_idnum() should not be NULL");
-      assert(old_method != new_method, "sanity check");
-
+      Method* new_method = old_method->get_new_method();
       default_methods()->at_put(index, new_method);
+
       if (log_is_enabled(Info, redefine, class, update)) {
         ResourceMark rm;
         if (!(*trace_name_printed)) {
@@ -3970,12 +3967,7 @@
 
 #if INCLUDE_JVMTI
 JvmtiCachedClassFileData* InstanceKlass::get_cached_class_file() {
-  if (MetaspaceShared::is_in_shared_metaspace(_cached_class_file)) {
-    // Ignore the archived class stream data
-    return NULL;
-  } else {
-    return _cached_class_file;
-  }
+  return _cached_class_file;
 }
 
 jint InstanceKlass::get_cached_class_file_len() {
@@ -3985,19 +3977,4 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
-
-#if INCLUDE_CDS
-JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() {
-  if (DumpSharedSpaces) {
-    return _cached_class_file;
-  } else {
-    assert(this->is_shared(), "class should be shared");
-    if (MetaspaceShared::is_in_shared_metaspace(_cached_class_file)) {
-      return _cached_class_file;
-    } else {
-      return NULL;
-    }
-  }
-}
 #endif
-#endif
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -847,14 +847,6 @@
   JvmtiCachedClassFieldMap* jvmti_cached_class_field_map() const {
     return _jvmti_cached_class_field_map;
   }
-
-#if INCLUDE_CDS
-  void set_archived_class_data(JvmtiCachedClassFileData* data) {
-    _cached_class_file = data;
-  }
-
-  JvmtiCachedClassFileData * get_archived_class_data();
-#endif // INCLUDE_CDS
 #else // INCLUDE_JVMTI
 
   static void purge_previous_versions(InstanceKlass* ik) { return; };
@@ -1149,7 +1141,7 @@
   Method* method_at_itable(Klass* holder, int index, TRAPS);
 
 #if INCLUDE_JVMTI
-  void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
+  void adjust_default_methods(bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
   void clean_weak_instanceklass_links();
--- a/src/hotspot/share/oops/klassVtable.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/klassVtable.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -942,21 +942,18 @@
 }
 
 // search the vtable for uses of either obsolete or EMCP methods
-void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+void klassVtable::adjust_method_entries(bool * trace_name_printed) {
   int prn_enabled = 0;
   for (int index = 0; index < length(); index++) {
     Method* old_method = unchecked_method_at(index);
-    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+    if (old_method == NULL || !old_method->is_old()) {
       continue; // skip uninteresting entries
     }
     assert(!old_method->is_deleted(), "vtable methods may not be deleted");
 
-    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+    Method* new_method = old_method->get_new_method();
+    put_method_at(new_method, index);
 
-    assert(new_method != NULL, "method_with_idnum() should not be NULL");
-    assert(old_method != new_method, "sanity check");
-
-    put_method_at(new_method, index);
     // For default methods, need to update the _default_methods array
     // which can only have one method entry for a given signature
     bool updated_default = false;
@@ -1272,21 +1269,16 @@
 
 #if INCLUDE_JVMTI
 // search the itable for uses of either obsolete or EMCP methods
-void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+void klassItable::adjust_method_entries(bool * trace_name_printed) {
 
   itableMethodEntry* ime = method_entry(0);
   for (int i = 0; i < _size_method_table; i++, ime++) {
     Method* old_method = ime->method();
-    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+    if (old_method == NULL || !old_method->is_old()) {
       continue; // skip uninteresting entries
     }
     assert(!old_method->is_deleted(), "itable methods may not be deleted");
-
-    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
-
-    assert(new_method != NULL, "method_with_idnum() should not be NULL");
-    assert(old_method != new_method, "sanity check");
-
+    Method* new_method = old_method->get_new_method();
     ime->initialize(new_method);
 
     if (log_is_enabled(Info, redefine, class, update)) {
--- a/src/hotspot/share/oops/klassVtable.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/klassVtable.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -103,7 +103,7 @@
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   bool adjust_default_method(int vtable_index, Method* old_method, Method* new_method);
-  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
+  void adjust_method_entries(bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_vtable();
 #endif // INCLUDE_JVMTI
@@ -322,7 +322,7 @@
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
-  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
+  void adjust_method_entries(bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_itable();
 #endif // INCLUDE_JVMTI
--- a/src/hotspot/share/oops/method.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/method.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -2120,7 +2120,8 @@
   // Can't assert the method_holder is the same because the new method has the
   // scratch method holder.
   assert(resolve_jmethod_id(jmid)->method_holder()->class_loader()
-           == new_method->method_holder()->class_loader(),
+           == new_method->method_holder()->class_loader() ||
+           new_method->method_holder()->class_loader() == NULL, // allow Unsafe substitution
          "changing to a different class loader");
   // Just change the method in place, jmethodID pointer doesn't change.
   *((Method**)jmid) = new_method;
--- a/src/hotspot/share/oops/method.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/oops/method.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -974,6 +974,15 @@
   // Deallocation function for redefine classes or if an error occurs
   void deallocate_contents(ClassLoaderData* loader_data);
 
+  Method* get_new_method() const {
+    InstanceKlass* holder = method_holder();
+    Method* new_method = holder->method_with_idnum(orig_method_idnum());
+
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    assert(this != new_method, "sanity check");
+    return new_method;
+  }
+
   // Printing
 #ifndef PRODUCT
   void print_on(outputStream* st) const;
--- a/src/hotspot/share/prims/evmCompat.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "utilities/debug.hpp"
-
-// This file contains definitions for functions that exist
-// in the ExactVM, but not in HotSpot. They are stubbed out
-// here to prevent linker errors when attempting to use HotSpot
-// with the ExactVM jdk.
-
-extern "C" void JVM_Process_DestroyProcess(void);
-extern "C" void JVM_Process_ForkAndExec(void);
-extern "C" void JVM_Process_WaitForProcessExit(void);
-extern "C" void gc(void);
-
-void JVM_Process_DestroyProcess(void) {
-  ShouldNotReachHere();
-}
-
-void JVM_Process_ForkAndExec(void) {
-  ShouldNotReachHere();
-}
-
-void JVM_Process_WaitForProcessExit(void) {
-  ShouldNotReachHere();
-}
-
-void gc(void) {
-  ShouldNotReachHere();
-}
--- a/src/hotspot/share/prims/jni.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/prims/jni.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -3953,9 +3953,6 @@
     }
 #endif
 
-    // Tracks the time application was running before GC
-    RuntimeService::record_application_start();
-
     // Notify JVMTI
     if (JvmtiExport::should_post_thread_life()) {
        JvmtiExport::post_thread_start(thread);
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -62,10 +62,11 @@
 Method**  VM_RedefineClasses::_matching_new_methods = NULL;
 Method**  VM_RedefineClasses::_deleted_methods      = NULL;
 Method**  VM_RedefineClasses::_added_methods        = NULL;
-int         VM_RedefineClasses::_matching_methods_length = 0;
-int         VM_RedefineClasses::_deleted_methods_length  = 0;
-int         VM_RedefineClasses::_added_methods_length    = 0;
-Klass*      VM_RedefineClasses::_the_class = NULL;
+int       VM_RedefineClasses::_matching_methods_length = 0;
+int       VM_RedefineClasses::_deleted_methods_length  = 0;
+int       VM_RedefineClasses::_added_methods_length    = 0;
+bool      VM_RedefineClasses::_has_redefined_Object = false;
+bool      VM_RedefineClasses::_has_null_class_loader = false;
 
 
 VM_RedefineClasses::VM_RedefineClasses(jint class_count,
@@ -76,6 +77,9 @@
   _class_load_kind = class_load_kind;
   _any_class_has_resolved_methods = false;
   _res = JVMTI_ERROR_NONE;
+  _the_class = NULL;
+  _has_redefined_Object = false;
+  _has_null_class_loader = false;
 }
 
 static inline InstanceKlass* get_ik(jclass def) {
@@ -214,11 +218,12 @@
   // Flush all compiled code that depends on the classes redefined.
   flush_dependent_code();
 
-  // Clean out MethodData pointing to old Method*
+  // Adjust constantpool caches and vtables for all classes
+  // that reference methods of the evolved classes.
   // Have to do this after all classes are redefined and all methods that
   // are redefined are marked as old.
-  MethodDataCleaner clean_weak_method_links;
-  ClassLoaderDataGraph::classes_do(&clean_weak_method_links);
+  AdjustAndCleanMetadata adjust_and_clean_metadata(thread);
+  ClassLoaderDataGraph::classes_do(&adjust_and_clean_metadata);
 
   // JSR-292 support
   if (_any_class_has_resolved_methods) {
@@ -3415,25 +3420,35 @@
 // Unevolving classes may point to methods of the_class directly
 // from their constant pool caches, itables, and/or vtables. We
 // use the ClassLoaderDataGraph::classes_do() facility and this helper
-// to fix up these pointers.
+// to fix up these pointers.  MethodData also points to old methods and
+// must be cleaned.
 
 // Adjust cpools and vtables closure
-void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
+void VM_RedefineClasses::AdjustAndCleanMetadata::do_klass(Klass* k) {
 
   // This is a very busy routine. We don't want too much tracing
   // printed out.
   bool trace_name_printed = false;
-  InstanceKlass *the_class = InstanceKlass::cast(_the_class);
 
   // If the class being redefined is java.lang.Object, we need to fix all
   // array class vtables also
-  if (k->is_array_klass() && _the_class == SystemDictionary::Object_klass()) {
-    k->vtable().adjust_method_entries(the_class, &trace_name_printed);
+  if (k->is_array_klass() && _has_redefined_Object) {
+    k->vtable().adjust_method_entries(&trace_name_printed);
 
   } else if (k->is_instance_klass()) {
     HandleMark hm(_thread);
     InstanceKlass *ik = InstanceKlass::cast(k);
 
+    // Clean MethodData of this class's methods so they don't refer to
+    // old methods that are no longer running.
+    Array<Method*>* methods = ik->methods();
+    int num_methods = methods->length();
+    for (int index = 0; index < num_methods; ++index) {
+      if (methods->at(index)->method_data() != NULL) {
+        methods->at(index)->method_data()->clean_weak_method_links();
+      }
+    }
+
     // HotSpot specific optimization! HotSpot does not currently
     // support delegation from the bootstrap class loader to a
     // user-defined class loader. This means that if the bootstrap
@@ -3446,57 +3461,29 @@
     // If the current class being redefined has a user-defined class
     // loader as its defining class loader, then we can skip all
     // classes loaded by the bootstrap class loader.
-    bool is_user_defined = (_the_class->class_loader() != NULL);
-    if (is_user_defined && ik->class_loader() == NULL) {
+    if (!_has_null_class_loader && ik->class_loader() == NULL) {
       return;
     }
 
-    // Fix the vtable embedded in the_class and subclasses of the_class,
-    // if one exists. We discard scratch_class and we don't keep an
-    // InstanceKlass around to hold obsolete methods so we don't have
-    // any other InstanceKlass embedded vtables to update. The vtable
-    // holds the Method*s for virtual (but not final) methods.
-    // Default methods, or concrete methods in interfaces are stored
-    // in the vtable, so if an interface changes we need to check
-    // adjust_method_entries() for every InstanceKlass, which will also
-    // adjust the default method vtable indices.
-    // We also need to adjust any default method entries that are
-    // not yet in the vtable, because the vtable setup is in progress.
-    // This must be done after we adjust the default_methods and
-    // default_vtable_indices for methods already in the vtable.
-    // If redefining Unsafe, walk all the vtables looking for entries.
-    if (ik->vtable_length() > 0 && (_the_class->is_interface()
-        || _the_class == SystemDictionary::internal_Unsafe_klass()
-        || ik->is_subtype_of(_the_class))) {
-      // ik->vtable() creates a wrapper object; rm cleans it up
-      ResourceMark rm(_thread);
-
-      ik->vtable().adjust_method_entries(the_class, &trace_name_printed);
-      ik->adjust_default_methods(the_class, &trace_name_printed);
+    // Adjust all vtables, default methods and itables, to clean out old methods.
+    ResourceMark rm(_thread);
+    if (ik->vtable_length() > 0) {
+      ik->vtable().adjust_method_entries(&trace_name_printed);
+      ik->adjust_default_methods(&trace_name_printed);
     }
 
-    // If the current class has an itable and we are either redefining an
-    // interface or if the current class is a subclass of the_class, then
-    // we potentially have to fix the itable. If we are redefining an
-    // interface, then we have to call adjust_method_entries() for
-    // every InstanceKlass that has an itable since there isn't a
-    // subclass relationship between an interface and an InstanceKlass.
-    // If redefining Unsafe, walk all the itables looking for entries.
-    if (ik->itable_length() > 0 && (_the_class->is_interface()
-        || _the_class == SystemDictionary::internal_Unsafe_klass()
-        || ik->is_subclass_of(_the_class))) {
-      ResourceMark rm(_thread);
-      ik->itable().adjust_method_entries(the_class, &trace_name_printed);
+    if (ik->itable_length() > 0) {
+      ik->itable().adjust_method_entries(&trace_name_printed);
     }
 
     // The constant pools in other classes (other_cp) can refer to
-    // methods in the_class. We have to update method information in
+    // old methods.  We have to update method information in
     // other_cp's cache. If other_cp has a previous version, then we
     // have to repeat the process for each previous version. The
     // constant pool cache holds the Method*s for non-virtual
     // methods and for virtual, final methods.
     //
-    // Special case: if the current class is the_class, then new_cp
+    // Special case: if the current class being redefined, then new_cp
     // has already been attached to the_class and old_cp has already
     // been added as a previous version. The new_cp doesn't have any
     // cached references to old methods so it doesn't need to be
@@ -3505,12 +3492,12 @@
     constantPoolHandle other_cp;
     ConstantPoolCache* cp_cache;
 
-    if (ik != _the_class) {
+    if (!ik->is_being_redefined()) {
       // this klass' constant pool cache may need adjustment
       other_cp = constantPoolHandle(ik->constants());
       cp_cache = other_cp->cache();
       if (cp_cache != NULL) {
-        cp_cache->adjust_method_entries(the_class, &trace_name_printed);
+        cp_cache->adjust_method_entries(&trace_name_printed);
       }
     }
 
@@ -3520,23 +3507,7 @@
          pv_node = pv_node->previous_versions()) {
       cp_cache = pv_node->constants()->cache();
       if (cp_cache != NULL) {
-        cp_cache->adjust_method_entries(pv_node, &trace_name_printed);
-      }
-    }
-  }
-}
-
-// Clean method data for this class
-void VM_RedefineClasses::MethodDataCleaner::do_klass(Klass* k) {
-  if (k->is_instance_klass()) {
-    InstanceKlass *ik = InstanceKlass::cast(k);
-    // Clean MethodData of this class's methods so they don't refer to
-    // old methods that are no longer running.
-    Array<Method*>* methods = ik->methods();
-    int num_methods = methods->length();
-    for (int index = 0; index < num_methods; ++index) {
-      if (methods->at(index)->method_data() != NULL) {
-        methods->at(index)->method_data()->clean_weak_method_links();
+        cp_cache->adjust_method_entries(&trace_name_printed);
       }
     }
   }
@@ -3554,6 +3525,15 @@
              "should be replaced");
     }
   }
+  // Update deleted jmethodID
+  for (int j = 0; j < _deleted_methods_length; ++j) {
+    Method* old_method = _deleted_methods[j];
+    jmethodID jmid = old_method->find_jmethod_id_or_null();
+    if (jmid != NULL) {
+      // Change the jmethodID to point to NSME.
+      Method::change_method_associated_with_jmethod_id(jmid, Universe::throw_no_such_method_error());
+    }
+  }
 }
 
 int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
@@ -3972,6 +3952,10 @@
 
   InstanceKlass* the_class = get_ik(the_jclass);
 
+  // Set some flags to control and optimize adjusting method entries
+  _has_redefined_Object |= the_class == SystemDictionary::Object_klass();
+  _has_null_class_loader |= the_class->class_loader() == NULL;
+
   // Remove all breakpoints in methods of this class
   JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
   jvmti_breakpoints.clearall_in_class_at_safepoint(the_class);
@@ -4193,11 +4177,6 @@
     _timer_rsc_phase2.start();
   }
 
-  // Adjust constantpool caches and vtables for all classes
-  // that reference methods of the evolved class.
-  AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
-  ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
-
   if (the_class->oop_map_cache() != NULL) {
     // Flush references to any obsolete methods from the oop map cache
     // so that obsolete methods are not pinned.
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -338,20 +338,22 @@
 class VM_RedefineClasses: public VM_Operation {
  private:
   // These static fields are needed by ClassLoaderDataGraph::classes_do()
-  // facility and the AdjustCpoolCacheAndVtable helper:
+  // facility and the CheckClass and AdjustAndCleanMetadata helpers.
   static Array<Method*>* _old_methods;
   static Array<Method*>* _new_methods;
-  static Method**      _matching_old_methods;
-  static Method**      _matching_new_methods;
-  static Method**      _deleted_methods;
-  static Method**      _added_methods;
+  static Method**        _matching_old_methods;
+  static Method**        _matching_new_methods;
+  static Method**        _deleted_methods;
+  static Method**        _added_methods;
   static int             _matching_methods_length;
   static int             _deleted_methods_length;
   static int             _added_methods_length;
-  static Klass*          _the_class;
+  static bool            _has_redefined_Object;
+  static bool            _has_null_class_loader;
 
   // The instance fields are used to pass information from
   // doit_prologue() to doit() and doit_epilogue().
+  Klass*                      _the_class;
   jint                        _class_count;
   const jvmtiClassDefinition *_class_defs;  // ptr to _class_count defs
 
@@ -513,20 +515,14 @@
   // Unevolving classes may point to methods of the_class directly
   // from their constant pool caches, itables, and/or vtables. We
   // use the ClassLoaderDataGraph::classes_do() facility and this helper
-  // to fix up these pointers.
-  class AdjustCpoolCacheAndVtable : public KlassClosure {
+  // to fix up these pointers and clean MethodData out.
+  class AdjustAndCleanMetadata : public KlassClosure {
     Thread* _thread;
    public:
-    AdjustCpoolCacheAndVtable(Thread* t) : _thread(t) {}
+    AdjustAndCleanMetadata(Thread* t) : _thread(t) {}
     void do_klass(Klass* k);
   };
 
-  // Clean MethodData out
-  class MethodDataCleaner : public KlassClosure {
-   public:
-    MethodDataCleaner() {}
-    void do_klass(Klass* k);
-  };
  public:
   VM_RedefineClasses(jint class_count,
                      const jvmtiClassDefinition *class_defs,
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,18 +120,21 @@
   return entry;
 }
 
-oop ResolvedMethodTable::add_method(Handle resolved_method_name) {
+oop ResolvedMethodTable::add_method(const methodHandle& m, Handle resolved_method_name) {
   MutexLocker ml(ResolvedMethodTable_lock);
   DEBUG_ONLY(NoSafepointVerifier nsv);
 
+  Method* method = m();
   // Check if method has been redefined while taking out ResolvedMethodTable_lock, if so
-  // use new method.
-  Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method_name());
-  assert(method->is_method(), "must be method");
+  // use new method.  The old method won't be deallocated because it's passed in as a Handle.
   if (method->is_old()) {
     // Replace method with redefined version
     InstanceKlass* holder = method->method_holder();
     method = holder->method_with_idnum(method->method_idnum());
+    if (method == NULL) {
+      // Replace deleted method with NSME.
+      method = Universe::throw_no_such_method_error();
+    }
     java_lang_invoke_ResolvedMethodName::set_vmtarget(resolved_method_name(), method);
   }
   // Set flag in class to indicate this InstanceKlass has entries in the table
@@ -226,18 +229,9 @@
 
       if (old_method->is_old()) {
 
-        if (old_method->is_deleted()) {
-          // leave deleted method in ResolvedMethod for now (this is a bug that we don't mark
-          // these on_stack)
-          continue;
-        }
-
-        InstanceKlass* holder = old_method->method_holder();
-        Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
-        assert(holder == new_method->method_holder(), "call after swapping redefined guts");
-        assert(new_method != NULL, "method_with_idnum() should not be NULL");
-        assert(old_method != new_method, "sanity check");
-
+        Method* new_method = (old_method->is_deleted()) ?
+                              Universe::throw_no_such_method_error() :
+                              old_method->get_new_method();
         java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, new_method);
 
         ResourceMark rm;
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/prims/resolvedMethodTable.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -89,7 +89,7 @@
 
   // Called from java_lang_invoke_ResolvedMethodName
   static oop find_method(Method* method);
-  static oop add_method(Handle rmethod_name);
+  static oop add_method(const methodHandle& method, Handle rmethod_name);
 
   static bool has_work() { return _dead_entries; }
   static void trigger_cleanup();
--- a/src/hotspot/share/runtime/init.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/init.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -174,10 +174,7 @@
       ObjectSynchronizer::audit_and_print_stats(true /* on_exit */);
     }
     perfMemory_exit();
-    if (log_is_enabled(Debug, safepoint, stats)) {
-      // Print the collected safepoint statistics.
-      SafepointSynchronize::print_stat_on_exit();
-    }
+    SafepointTracing::statistics_exit_log();
     if (PrintStringTableStatistics) {
       SymbolTable::dump(tty);
       StringTable::dump(tty);
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -150,6 +150,9 @@
 #if INCLUDE_NMT
 Mutex*   NMTQuery_lock                = NULL;
 #endif
+#if INCLUDE_CDS && INCLUDE_JVMTI
+Mutex*   CDSClassFileStream_lock      = NULL;
+#endif
 
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -339,6 +342,9 @@
 #if INCLUDE_NMT
   def(NMTQuery_lock                , PaddedMutex  , max_nonleaf, false, Monitor::_safepoint_check_always);
 #endif
+#if INCLUDE_CDS && INCLUDE_JVMTI
+  def(CDSClassFileStream_lock      , PaddedMutex  , max_nonleaf, false, Monitor::_safepoint_check_always);
+#endif
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -133,6 +133,9 @@
 #if INCLUDE_NMT
 extern Mutex*   NMTQuery_lock;                   // serialize NMT Dcmd queries
 #endif
+#if INCLUDE_CDS && INCLUDE_JVMTI
+extern Mutex*   CDSClassFileStream_lock;         // FileMapInfo::open_stream_for_jvmti
+#endif
 #if INCLUDE_JFR
 extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
 extern Monitor* JfrMsg_lock;                     // protects JFR messaging
--- a/src/hotspot/share/runtime/safepoint.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/safepoint.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -103,16 +103,6 @@
   }
 }
 
-static void post_safepoint_wait_blocked_event(EventSafepointWaitBlocked& event,
-                                              uint64_t safepoint_id,
-                                              int initial_threads_waiting_to_block) {
-  if (event.should_commit()) {
-    event.set_safepointId(safepoint_id);
-    event.set_runningThreadCount(initial_threads_waiting_to_block);
-    event.commit();
-  }
-}
-
 static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask& event,
                                               uint64_t safepoint_id,
                                               const char* name) {
@@ -138,27 +128,21 @@
 volatile uint64_t SafepointSynchronize::_safepoint_counter = 0;
 const uint64_t SafepointSynchronize::InactiveSafepointCounter = 0;
 int SafepointSynchronize::_current_jni_active_count = 0;
-long SafepointSynchronize::_end_of_last_safepoint = 0;
 
 WaitBarrier* SafepointSynchronize::_wait_barrier;
 
-// We need a place to save the desc since it is released before we need it.
-static char stopped_description[64] = "";
-static bool _vm_is_waiting = false;
-
 static volatile bool PageArmed = false;        // safepoint polling page is RO|RW vs PROT_NONE
 static bool timeout_error_printed = false;
 
 // Statistic related
-julong SafepointSynchronize::_coalesced_vmop_count = 0;
 static jlong _safepoint_begin_time = 0;
-static float _ts_of_current_safepoint = 0.0f;
 static volatile int _nof_threads_hit_polling_page = 0;
 
 void SafepointSynchronize::init(Thread* vmthread) {
   // WaitBarrier should never be destroyed since we will have
   // threads waiting on it while exiting.
   _wait_barrier = new WaitBarrier(vmthread);
+  SafepointTracing::init();
 }
 
 void SafepointSynchronize::increment_jni_active_count() {
@@ -244,16 +228,13 @@
   DEBUG_ONLY(assert_list_is_valid(tss_head, still_running);)
 
   *initial_running = still_running;
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    begin_statistics(nof_threads, still_running);
-  }
 
   int iterations = 1; // The first iteration is above.
 
   while (still_running > 0) {
     // Check if this has taken too long:
     if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
-      print_safepoint_timeout(_spinning_timeout);
+      print_safepoint_timeout();
     }
     if (int(iterations) == -1) { // overflow - something is wrong.
       // We can only overflow here when we are using global
@@ -291,9 +272,6 @@
 
   assert(tss_head == NULL, "Must be empty");
 
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    update_statistics_on_spin_end();
-  }
   return iterations;
 }
 
@@ -303,8 +281,11 @@
   // stopped by different mechanisms:
   //
   //  1. Running interpreted
-  //     The interpreter dispatch table is changed to force it to
-  //     check for a safepoint condition between bytecodes.
+  //     When executing branching/returning byte codes interpreter
+  //     checks if the poll is armed, if so blocks in SS::block().
+  //     When using global polling the interpreter dispatch table
+  //     is changed to force it to check for a safepoint condition
+  //     between bytecodes.
   //  2. Running in native code
   //     When returning from the native code, a Java thread must check
   //     the safepoint _state to see if we must block.  If the
@@ -322,9 +303,9 @@
   //     block condition until the safepoint operation is complete.
   //  5. In VM or Transitioning between states
   //     If a Java thread is currently running in the VM or transitioning
-  //     between states, the safepointing code will wait for the thread to
-  //     block itself when it attempts transitions to a new state.
-  //
+  //     between states, the safepointing code will poll the thread state
+  //     until the thread blocks itself when it attempts transitions to a
+  //     new state or locking a safepoint checked monitor.
 
   // We must never miss a thread with correct safepoint id, so we must make sure we arm
   // the wait barrier for the next safepoint id/counter.
@@ -363,17 +344,10 @@
 
 // Roll all threads forward to a safepoint and suspend them all
 void SafepointSynchronize::begin() {
-  EventSafepointBegin begin_event;
   assert(Thread::current()->is_VM_thread(), "Only VM thread may execute a safepoint");
 
-  strncpy(stopped_description, VMThread::vm_safepoint_description(), sizeof(stopped_description) - 1);
-  stopped_description[sizeof(stopped_description) - 1] = '\0';
-
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    _safepoint_begin_time = os::javaTimeNanos();
-    _ts_of_current_safepoint = tty->time_stamp().seconds();
-    _nof_threads_hit_polling_page = 0;
-  }
+  EventSafepointBegin begin_event;
+  SafepointTracing::begin(VMThread::vm_op_type());
 
   Universe::heap()->safepoint_synchronize_begin();
 
@@ -385,10 +359,10 @@
 
   int nof_threads = Threads::number_of_threads();
 
+  _nof_threads_hit_polling_page = 0;
+
   log_debug(safepoint)("Safepoint synchronization initiated using %s wait barrier. (%d threads)", _wait_barrier->description(), nof_threads);
 
-  RuntimeService::record_safepoint_begin();
-
   // Reset the count of active JNI critical threads
   _current_jni_active_count = 0;
 
@@ -399,9 +373,9 @@
   if (SafepointTimeout) {
     // Set the limit time, so that it can be compared to see if this has taken
     // too long to complete.
-    safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
+    safepoint_limit_time = SafepointTracing::start_of_safepoint() + (jlong)SafepointTimeoutDelay * (NANOUNITS / MILLIUNITS);
+    timeout_error_printed = false;
   }
-  timeout_error_printed = false;
 
   EventSafepointStateSynchronization sync_event;
   int initial_running = 0;
@@ -413,20 +387,13 @@
   int iterations = synchronize_threads(safepoint_limit_time, nof_threads, &initial_running);
   assert(_waiting_to_block == 0, "No thread should be running");
 
-  post_safepoint_synchronize_event(sync_event, _safepoint_counter, initial_running,
-                                   _waiting_to_block, iterations);
-
-  // Keep event from now.
-  EventSafepointWaitBlocked wait_blocked_event;
-
 #ifndef PRODUCT
-  if (SafepointTimeout) {
+  if (safepoint_limit_time != 0) {
     jlong current_time = os::javaTimeNanos();
     if (safepoint_limit_time < current_time) {
       log_warning(safepoint)("# SafepointSynchronize: Finished after "
                     INT64_FORMAT_W(6) " ms",
-                    (int64_t)((current_time - safepoint_limit_time) / MICROUNITS +
-                              (jlong)SafepointTimeoutDelay));
+                    (int64_t)(current_time - SafepointTracing::start_of_safepoint()) / (NANOUNITS / MILLIUNITS));
     }
   }
 #endif
@@ -438,8 +405,6 @@
 
   OrderAccess::fence();
 
-  post_safepoint_wait_blocked_event(wait_blocked_event, _safepoint_counter, 0);
-
 #ifdef ASSERT
   // Make sure all the threads were visited.
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
@@ -450,12 +415,12 @@
   // Update the count of active JNI critical regions
   GCLocker::set_jni_lock_count(_current_jni_active_count);
 
-  log_info(safepoint)("Entering safepoint region: %s", stopped_description);
+  post_safepoint_synchronize_event(sync_event,
+                                   _safepoint_counter,
+                                   initial_running,
+                                   _waiting_to_block, iterations);
 
-  RuntimeService::record_safepoint_synchronized();
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    update_statistics_on_sync_end(os::javaTimeNanos());
-  }
+  SafepointTracing::synchronized(nof_threads, initial_running, _nof_threads_hit_polling_page);
 
   // We do the safepoint cleanup first since a GC related safepoint
   // needs cleanup to be completed before running the GC op.
@@ -463,12 +428,8 @@
   do_cleanup_tasks();
   post_safepoint_cleanup_event(cleanup_event, _safepoint_counter);
 
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    // Record how much time spend on the above cleanup tasks
-    update_statistics_on_cleanup_end(os::javaTimeNanos());
-  }
-
   post_safepoint_begin_event(begin_event, _safepoint_counter, nof_threads, _current_jni_active_count);
+  SafepointTracing::cleanup();
 }
 
 void SafepointSynchronize::disarm_safepoint() {
@@ -520,10 +481,6 @@
     }
   } // ~JavaThreadIteratorWithHandle
 
-  log_info(safepoint)("Leaving safepoint region");
-
-  RuntimeService::record_safepoint_end();
-
   // Release threads lock, so threads can be created/destroyed again.
   Threads_lock->unlock();
 
@@ -539,19 +496,11 @@
   uint64_t safepoint_id = _safepoint_counter;
   assert(Thread::current()->is_VM_thread(), "Only VM thread can execute a safepoint");
 
-  if (log_is_enabled(Debug, safepoint, stats)) {
-    end_statistics(os::javaTimeNanos());
-  }
-
   disarm_safepoint();
 
-  RuntimeService::record_safepoint_epilog(stopped_description);
-
   Universe::heap()->safepoint_synchronize_end();
 
-  // record this time so VMThread can keep track how much time has elapsed
-  // since last safepoint.
-  _end_of_last_safepoint = os::javaTimeMillis();
+  SafepointTracing::end();
 
   post_safepoint_end_event(event, safepoint_id);
 }
@@ -915,7 +864,7 @@
     assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
   }
 
-  if (log_is_enabled(Debug, safepoint, stats)) {
+  if (log_is_enabled(Info, safepoint, stats)) {
     Atomic::inc(&_nof_threads_hit_polling_page);
   }
 
@@ -925,7 +874,7 @@
 }
 
 
-void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason) {
+void SafepointSynchronize::print_safepoint_timeout() {
   if (!timeout_error_printed) {
     timeout_error_printed = true;
     // Print out the thread info which didn't reach the safepoint for debugging
@@ -937,20 +886,10 @@
 
       ls.cr();
       ls.print_cr("# SafepointSynchronize::begin: Timeout detected:");
-      if (reason ==  _spinning_timeout) {
-        ls.print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint.");
-      } else if (reason == _blocking_timeout) {
-        ls.print_cr("# SafepointSynchronize::begin: Timed out while waiting for threads to stop.");
-      }
-
+      ls.print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint.");
       ls.print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
-      ThreadSafepointState *cur_state;
       for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) {
-        cur_state = cur_thread->safepoint_state();
-
-        if (cur_thread->thread_state() != _thread_blocked &&
-          ((reason == _spinning_timeout && cur_state->is_running()) ||
-             (reason == _blocking_timeout))) {
+        if (cur_thread->safepoint_state()->is_running()) {
           ls.print("# ");
           cur_thread->print_on(&ls);
           ls.cr();
@@ -964,11 +903,10 @@
   // ShowMessageBoxOnError.
   if (AbortVMOnSafepointTimeout) {
     fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
-          SafepointTimeoutDelay, VMThread::vm_safepoint_description());
+          SafepointTimeoutDelay, VMThread::vm_operation()->name());
   }
 }
 
-
 // -------------------------------------------------------------------------------------------------------
 // Implementation of ThreadSafepointState
 
@@ -1176,108 +1114,25 @@
 }
 
 
-//
-//                     Statistics & Instrumentations
-//
-struct SafepointStats {
-    float  _time_stamp;                        // record when the current safepoint occurs in seconds
-    int    _vmop_type;                         // tyep of VM operation triggers the safepoint
-    int    _nof_total_threads;                 // total number of Java threads
-    int    _nof_initial_running_threads;       // total number of initially seen running threads
-    int    _nof_threads_wait_to_block;         // total number of threads waiting for to block
-    bool   _page_armed;                        // true if polling page is armed, false otherwise
-    int _nof_threads_hit_page_trap;            // total number of threads hitting the page trap
-    jlong  _time_to_spin;                      // total time in millis spent in spinning
-    jlong  _time_to_wait_to_block;             // total time in millis spent in waiting for to block
-    jlong  _time_to_do_cleanups;               // total time in millis spent in performing cleanups
-    jlong  _time_to_sync;                      // total time in millis spent in getting to _synchronized
-    jlong  _time_to_exec_vmop;                 // total time in millis spent in vm operation itself
-};
+// -------------------------------------------------------------------------------------------------------
+// Implementation of SafepointTracing
 
-static const int _statistics_header_count = 30;
-static int _cur_stat_index = 0;
-static SafepointStats safepoint_stats = {0};  // zero initialize
-static SafepointStats* spstat = &safepoint_stats;
+jlong SafepointTracing::_last_safepoint_begin_time_ns = 0;
+jlong SafepointTracing::_last_safepoint_sync_time_ns = 0;
+jlong SafepointTracing::_last_safepoint_cleanup_time_ns = 0;
+jlong SafepointTracing::_last_safepoint_end_time_ns = 0;
+jlong SafepointTracing::_last_app_time_ns = 0;
+int SafepointTracing::_nof_threads = 0;
+int SafepointTracing::_nof_running = 0;
+int SafepointTracing::_page_trap = 0;
+VM_Operation::VMOp_Type SafepointTracing::_current_type;
+jlong     SafepointTracing::_max_sync_time = 0;
+jlong     SafepointTracing::_max_vmop_time = 0;
+uint64_t  SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0};
 
-static julong _safepoint_reasons[VM_Operation::VMOp_Terminating];
-static jlong  _max_sync_time = 0;
-static jlong  _max_vmop_time = 0;
-
-static jlong  cleanup_end_time = 0;
-
-void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
-
-  spstat->_time_stamp = _ts_of_current_safepoint;
-
-  VM_Operation *op = VMThread::vm_operation();
-  spstat->_vmop_type = op != NULL ? op->type() : VM_Operation::VMOp_None;
-  _safepoint_reasons[spstat->_vmop_type]++;
-
-  spstat->_nof_total_threads = nof_threads;
-  spstat->_nof_initial_running_threads = nof_running;
-
-  // Records the start time of spinning. The real time spent on spinning
-  // will be adjusted when spin is done. Same trick is applied for time
-  // spent on waiting for threads to block.
-  if (nof_running != 0) {
-    spstat->_time_to_spin = os::javaTimeNanos();
-  }  else {
-    spstat->_time_to_spin = 0;
-  }
-}
-
-void SafepointSynchronize::update_statistics_on_spin_end() {
-  jlong cur_time = os::javaTimeNanos();
-
-  spstat->_nof_threads_wait_to_block = _waiting_to_block;
-  if (spstat->_nof_initial_running_threads != 0) {
-    spstat->_time_to_spin = cur_time - spstat->_time_to_spin;
-  }
-
-  // Records the start time of waiting for to block. Updated when block is done.
-  if (_waiting_to_block != 0) {
-    spstat->_time_to_wait_to_block = cur_time;
-  } else {
-    spstat->_time_to_wait_to_block = 0;
-  }
-}
-
-void SafepointSynchronize::update_statistics_on_sync_end(jlong end_time) {
-
-  if (spstat->_nof_threads_wait_to_block != 0) {
-    spstat->_time_to_wait_to_block = end_time -
-      spstat->_time_to_wait_to_block;
-  }
-
-  // Records the end time of sync which will be used to calculate the total
-  // vm operation time. Again, the real time spending in syncing will be deducted
-  // from the start of the sync time later when end_statistics is called.
-  spstat->_time_to_sync = end_time - _safepoint_begin_time;
-  if (spstat->_time_to_sync > _max_sync_time) {
-    _max_sync_time = spstat->_time_to_sync;
-  }
-
-  spstat->_time_to_do_cleanups = end_time;
-}
-
-void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) {
-
-  // Record how long spent in cleanup tasks.
-  spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups;
-  cleanup_end_time = end_time;
-}
-
-void SafepointSynchronize::end_statistics(jlong vmop_end_time) {
-
-  // Update the vm operation time.
-  spstat->_time_to_exec_vmop = vmop_end_time -  cleanup_end_time;
-  if (spstat->_time_to_exec_vmop > _max_vmop_time) {
-    _max_vmop_time = spstat->_time_to_exec_vmop;
-  }
-
-  spstat->_nof_threads_hit_page_trap = _nof_threads_hit_polling_page;
-
-  print_statistics();
+void SafepointTracing::init() {
+  // Application start
+  _last_safepoint_end_time_ns = os::javaTimeNanos();
 }
 
 // Helper method to print the header.
@@ -1285,66 +1140,121 @@
   // The number of spaces is significant here, and should match the format
   // specifiers in print_statistics().
 
-  st->print("          vmop                            "
-            "[ threads:    total initially_running wait_to_block ]"
-            "[ time:    spin   block    sync cleanup    vmop ] ");
+  st->print("VM Operation                 "
+            "[ threads: total initial_running ]"
+            "[ time:       sync    cleanup       vmop      total ]");
 
-  st->print_cr("page_trap_count");
+  st->print_cr(" page_trap_count");
 }
 
 // This prints a nice table.  To get the statistics to not shift due to the logging uptime
-// decorator, use the option as: -Xlog:safepoint+stats=debug:[outputfile]:none
-void SafepointSynchronize::print_statistics() {
-  LogTarget(Debug, safepoint, stats) lt;
+// decorator, use the option as: -Xlog:safepoint+stats:[outputfile]:none
+void SafepointTracing::statistics_log() {
+  LogTarget(Info, safepoint, stats) lt;
   assert (lt.is_enabled(), "should only be called when printing statistics is enabled");
   LogStream ls(lt);
 
+  static int _cur_stat_index = 0;
+
   // Print header every 30 entries
-  if ((_cur_stat_index % _statistics_header_count) == 0) {
+  if ((_cur_stat_index % 30) == 0) {
     print_header(&ls);
     _cur_stat_index = 1;  // wrap
   } else {
     _cur_stat_index++;
   }
 
-  ls.print("%8.3f: ", spstat->_time_stamp);
-  ls.print("%-28s  [          "
-           INT32_FORMAT_W(8) " " INT32_FORMAT_W(17) " " INT32_FORMAT_W(13) " "
+  ls.print("%-28s [       "
+           INT32_FORMAT_W(8) "        " INT32_FORMAT_W(8) " "
            "]",
-           VM_Operation::name(spstat->_vmop_type),
-           spstat->_nof_total_threads,
-           spstat->_nof_initial_running_threads,
-           spstat->_nof_threads_wait_to_block);
-  // "/ MICROUNITS " is to convert the unit from nanos to millis.
+           VM_Operation::name(_current_type),
+           _nof_threads,
+           _nof_running);
   ls.print("[       "
-           INT64_FORMAT_W(7) " " INT64_FORMAT_W(7) " "
-           INT64_FORMAT_W(7) " " INT64_FORMAT_W(7) " "
-           INT64_FORMAT_W(7) " ] ",
-           (int64_t)(spstat->_time_to_spin / MICROUNITS),
-           (int64_t)(spstat->_time_to_wait_to_block / MICROUNITS),
-           (int64_t)(spstat->_time_to_sync / MICROUNITS),
-           (int64_t)(spstat->_time_to_do_cleanups / MICROUNITS),
-           (int64_t)(spstat->_time_to_exec_vmop / MICROUNITS));
+           INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " "
+           INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]",
+           (int64_t)(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns),
+           (int64_t)(_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns),
+           (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns),
+           (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns));
 
-  ls.print_cr(INT32_FORMAT_W(15) " ", spstat->_nof_threads_hit_page_trap);
+  ls.print_cr(INT32_FORMAT_W(16), _page_trap);
 }
 
 // This method will be called when VM exits. This tries to summarize the sampling.
 // Current thread may already be deleted, so don't use ResourceMark.
-void SafepointSynchronize::print_stat_on_exit() {
-
+void SafepointTracing::statistics_exit_log() {
+  if (!log_is_enabled(Info, safepoint, stats)) {
+    return;
+  }
   for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
-    if (_safepoint_reasons[index] != 0) {
-      log_debug(safepoint, stats)("%-28s" UINT64_FORMAT_W(10), VM_Operation::name(index),
-                _safepoint_reasons[index]);
+    if (_op_count[index] != 0) {
+      log_info(safepoint, stats)("%-28s" UINT64_FORMAT_W(10), VM_Operation::name(index),
+               _op_count[index]);
     }
   }
 
-  log_debug(safepoint, stats)("VM operations coalesced during safepoint " INT64_FORMAT,
-                              _coalesced_vmop_count);
-  log_debug(safepoint, stats)("Maximum sync time  " INT64_FORMAT" ms",
-                              (int64_t)(_max_sync_time / MICROUNITS));
-  log_debug(safepoint, stats)("Maximum vm operation time (except for Exit VM operation)  "
-                              INT64_FORMAT " ms",
-                              (int64_t)(_max_vmop_time / MICROUNITS));
+  log_info(safepoint, stats)("VM operations coalesced during safepoint " INT64_FORMAT,
+                              VMThread::get_coalesced_count());
+  log_info(safepoint, stats)("Maximum sync time  " INT64_FORMAT" ns",
+                              (int64_t)(_max_sync_time));
+  log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation)  "
+                              INT64_FORMAT " ns",
+                              (int64_t)(_max_vmop_time));
 }
+
+void SafepointTracing::begin(VM_Operation::VMOp_Type type) {
+  _op_count[type]++;
+  _current_type = type;
+
+  // update the time stamp to begin recording safepoint time
+  _last_safepoint_begin_time_ns = os::javaTimeNanos();
+  _last_safepoint_sync_time_ns = 0;
+  _last_safepoint_cleanup_time_ns = 0;
+
+  _last_app_time_ns = _last_safepoint_begin_time_ns - _last_safepoint_end_time_ns;
+  _last_safepoint_end_time_ns = 0;
+
+  RuntimeService::record_safepoint_begin(_last_app_time_ns);
+}
+
+void SafepointTracing::synchronized(int nof_threads, int nof_running, int traps) {
+  _last_safepoint_sync_time_ns = os::javaTimeNanos();
+  _nof_threads = nof_threads;
+  _nof_running = nof_running;
+  _page_trap   = traps;
+  RuntimeService::record_safepoint_synchronized(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns);
+}
+
+void SafepointTracing::cleanup() {
+  _last_safepoint_cleanup_time_ns = os::javaTimeNanos();
+}
+
+void SafepointTracing::end() {
+  _last_safepoint_end_time_ns = os::javaTimeNanos();
+
+  if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) {
+    _max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns;
+  }
+  if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) {
+    _max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns;
+  }
+  if (log_is_enabled(Info, safepoint, stats)) {
+    statistics_log();
+  }
+
+  log_info(safepoint)(
+     "Safepoint \"%s\", "
+     "Time since last: " JLONG_FORMAT " ns, "
+     "Reaching safepoint: " JLONG_FORMAT " ns, "
+     "At safepoint: " JLONG_FORMAT " ns, "
+     "Total: " JLONG_FORMAT " ns",
+      VM_Operation::name(_current_type),
+      _last_app_time_ns,
+      _last_safepoint_cleanup_time_ns - _last_safepoint_begin_time_ns,
+      _last_safepoint_end_time_ns     - _last_safepoint_cleanup_time_ns,
+      _last_safepoint_end_time_ns     - _last_safepoint_begin_time_ns
+     );
+
+  RuntimeService::record_safepoint_end(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns);
+}
--- a/src/hotspot/share/runtime/safepoint.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/safepoint.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 #include "runtime/os.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/vmOperations.hpp"
 #include "utilities/ostream.hpp"
 #include "utilities/waitBarrier.hpp"
 
@@ -77,11 +78,6 @@
   friend class ThreadSafepointState;
   friend class HandshakeState;
 
-  enum SafepointTimeoutReason {
-    _spinning_timeout = 0,
-    _blocking_timeout = 1
-  };
-
   // Threads might read this flag directly, without acquiring the Threads_lock:
   static volatile SynchronizeState _state;
   // Number of threads we are waiting for to block:
@@ -110,7 +106,7 @@
   static void print_statistics();
 
   // For debug long safepoint
-  static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason);
+  static void print_safepoint_timeout();
 
   // Helper methods for safepoint procedure:
   static void arm_safepoint();
@@ -150,19 +146,9 @@
   // Exception handling for page polling
   static void handle_polling_page_exception(JavaThread *thread);
 
-  // VM Thread interface for determining safepoint rate
-  static long last_non_safepoint_interval() {
-    return os::javaTimeMillis() - _end_of_last_safepoint;
-  }
-  static long end_of_last_safepoint() {
-    return _end_of_last_safepoint;
-  }
   static bool is_cleanup_needed();
   static void do_cleanup_tasks();
 
-  static void print_stat_on_exit();
-  static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; }
-
   static void set_is_at_safepoint()             { _state = _synchronized; }
   static void set_is_not_at_safepoint()         { _state = _not_synchronized; }
 
@@ -247,6 +233,48 @@
   static void destroy(JavaThread *thread);
 };
 
+class SafepointTracing : public AllStatic {
+private:
+  // Absolute
+  static jlong _last_safepoint_begin_time_ns;
+  static jlong _last_safepoint_sync_time_ns;
+  static jlong _last_safepoint_cleanup_time_ns;
+  static jlong _last_safepoint_end_time_ns;
+  // Relative
+  static jlong _last_app_time_ns;
 
+  static int _nof_threads;
+  static int _nof_running;
+  static int _page_trap;
+
+  static VM_Operation::VMOp_Type _current_type;
+  static jlong     _max_sync_time;
+  static jlong     _max_vmop_time;
+  static uint64_t  _op_count[VM_Operation::VMOp_Terminating];
+
+  static void statistics_log();
+
+public:
+  static void init();
+
+  static void begin(VM_Operation::VMOp_Type type);
+  static void synchronized(int nof_threads, int nof_running, int traps);
+  static void cleanup();
+  static void end();
+
+  static void statistics_exit_log();
+
+  static jlong time_since_last_safepoint_ms() {
+    return (os::javaTimeNanos() - _last_safepoint_end_time_ns) / (NANOUNITS / MILLIUNITS);
+  }
+
+  static jlong end_of_last_safepoint_ms() {
+    return _last_safepoint_end_time_ns / (NANOUNITS / MILLIUNITS);
+  }
+
+  static jlong start_of_safepoint() {
+    return _last_safepoint_begin_time_ns;
+  }
+};
 
 #endif // SHARE_RUNTIME_SAFEPOINT_HPP
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -479,7 +479,7 @@
 
   // We don't update the rate if we've just came out of a safepoint.
   // delta_s is the time since last safepoint in milliseconds.
-  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+  jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms();
   jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
   // How many events were there since the last time?
   int event_count = m->invocation_count() + m->backedge_count();
@@ -504,7 +504,7 @@
 // Check if this method has been stale from a given number of milliseconds.
 // See select_task().
 bool TieredThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) {
-  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+  jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms();
   jlong delta_t = t - m->prev_time();
   if (delta_t > timeout && delta_s > timeout) {
     int event_count = m->invocation_count() + m->backedge_count();
--- a/src/hotspot/share/runtime/vmOperations.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/vmOperations.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -41,6 +41,7 @@
 // Note: When new VM_XXX comes up, add 'XXX' to the template table.
 #define VM_OPS_DO(template)                       \
   template(None)                                  \
+  template(Cleanup)                               \
   template(ThreadStop)                            \
   template(ThreadDump)                            \
   template(PrintThreads)                          \
@@ -213,7 +214,7 @@
 
   // Debugging
   virtual void print_on_error(outputStream* st) const;
-  const char* name() const { return _names[type()]; }
+  virtual const char* name() const  { return _names[type()]; }
   static const char* name(int type) {
     assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type");
     return _names[type];
@@ -223,6 +224,21 @@
 #endif
 };
 
+class VM_None: public VM_Operation {
+  const char* _reason;
+ public:
+  VM_None(const char* reason) : _reason(reason) {}
+  const char* name() const { return _reason; }
+  VMOp_Type type() const { return VMOp_None; }
+  void doit() {};
+};
+
+class VM_Cleanup: public VM_Operation {
+ public:
+  VMOp_Type type() const { return VMOp_Cleanup; }
+  void doit() {};
+};
+
 class VM_ThreadStop: public VM_Operation {
  private:
   oop     _thread;        // The Thread that the Throwable is thrown against
--- a/src/hotspot/share/runtime/vmThread.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/vmThread.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -48,19 +48,13 @@
 #include "utilities/vmError.hpp"
 #include "utilities/xmlstream.hpp"
 
-// Dummy VM operation to act as first element in our circular double-linked list
-class VM_None: public VM_Operation {
-  VMOp_Type type() const { return VMOp_None; }
-  void  doit() {};
-};
-
 VMOperationQueue::VMOperationQueue() {
   // The queue is a circular doubled-linked list, which always contains
   // one element (i.e., one element means empty).
   for(int i = 0; i < nof_priorities; i++) {
     _queue_length[i] = 0;
     _queue_counter = 0;
-    _queue[i] = new VM_None();
+    _queue[i] = new VM_None("QueueHead");
     _queue[i]->set_next(_queue[i]);
     _queue[i]->set_prev(_queue[i]);
   }
@@ -229,14 +223,14 @@
 //------------------------------------------------------------------------------------------------------------------
 // Implementation of VMThread stuff
 
-bool                VMThread::_should_terminate   = false;
+bool              VMThread::_should_terminate   = false;
 bool              VMThread::_terminated         = false;
 Monitor*          VMThread::_terminate_lock     = NULL;
 VMThread*         VMThread::_vm_thread          = NULL;
 VM_Operation*     VMThread::_cur_vm_operation   = NULL;
 VMOperationQueue* VMThread::_vm_queue           = NULL;
 PerfCounter*      VMThread::_perf_accumulated_vm_operation_time = NULL;
-const char*       VMThread::_no_op_reason       = NULL;
+uint64_t          VMThread::_coalesced_count = 0;
 VMOperationTimeoutTask* VMThread::_timeout_task = NULL;
 
 
@@ -283,6 +277,8 @@
   _vm_thread = NULL;      // VM thread is gone
 }
 
+static VM_None halt_op("Halt");
+
 void VMThread::run() {
   assert(this == vm_thread(), "check");
 
@@ -320,7 +316,7 @@
   }
 
   // 4526887 let VM thread exit at Safepoint
-  _no_op_reason = "Halt";
+  _cur_vm_operation = &halt_op;
   SafepointSynchronize::begin();
 
   if (VerifyBeforeExit) {
@@ -435,24 +431,25 @@
   }
 }
 
-bool VMThread::no_op_safepoint_needed(bool check_time) {
+static VM_None    safepointALot_op("SafepointALot");
+static VM_Cleanup cleanup_op;
+
+VM_Operation* VMThread::no_op_safepoint(bool check_time) {
   if (SafepointALot) {
-    _no_op_reason = "SafepointALot";
-    return true;
+    return &safepointALot_op;
   }
   if (!SafepointSynchronize::is_cleanup_needed()) {
-    return false;
+    return NULL;
   }
   if (check_time) {
-    long interval = SafepointSynchronize::last_non_safepoint_interval();
+    long interval_ms = SafepointTracing::time_since_last_safepoint_ms();
     bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
-                             (interval > GuaranteedSafepointInterval);
+                             (interval_ms > GuaranteedSafepointInterval);
     if (!max_time_exceeded) {
-      return false;
+      return NULL;
     }
   }
-  _no_op_reason = "Cleanup";
-  return true;
+  return &cleanup_op;
 }
 
 void VMThread::loop() {
@@ -494,7 +491,7 @@
           exit(-1);
         }
 
-        if (timedout && VMThread::no_op_safepoint_needed(false)) {
+        if (timedout && (_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) {
           MutexUnlockerEx mul(VMOperationQueue_lock,
                               Mutex::_no_safepoint_check_flag);
           // Force a safepoint since we have not had one for at least
@@ -506,6 +503,7 @@
             if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
           #endif
           SafepointSynchronize::end();
+          _cur_vm_operation = NULL;
         }
         _cur_vm_operation = _vm_queue->remove_next();
 
@@ -555,9 +553,7 @@
               _vm_queue->set_drain_list(next);
               evaluate_operation(_cur_vm_operation);
               _cur_vm_operation = next;
-              if (log_is_enabled(Debug, safepoint, stats)) {
-                SafepointSynchronize::inc_vmop_coalesced_count();
-              }
+              _coalesced_count++;
             } while (_cur_vm_operation != NULL);
           }
           // There is a chance that a thread enqueued a safepoint op
@@ -622,10 +618,11 @@
     //
     // We want to make sure that we get to a safepoint regularly.
     //
-    if (VMThread::no_op_safepoint_needed(true)) {
+    if ((_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) {
       HandleMark hm(VMThread::vm_thread());
       SafepointSynchronize::begin();
       SafepointSynchronize::end();
+      _cur_vm_operation = NULL;
     }
   }
 }
--- a/src/hotspot/share/runtime/vmThread.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/runtime/vmThread.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -119,12 +119,11 @@
   static bool _terminated;
   static Monitor * _terminate_lock;
   static PerfCounter* _perf_accumulated_vm_operation_time;
-
-  static const char* _no_op_reason;
+  static uint64_t _coalesced_count;
 
   static VMOperationTimeoutTask* _timeout_task;
 
-  static bool no_op_safepoint_needed(bool check_time);
+  static VM_Operation* no_op_safepoint(bool check_time);
 
   void evaluate_operation(VM_Operation* op);
 
@@ -155,9 +154,8 @@
 
   // Returns the current vm operation if any.
   static VM_Operation* vm_operation()             { return _cur_vm_operation; }
-
-  // Returns the current vm operation name or set reason
-  static const char* vm_safepoint_description()   { return _cur_vm_operation != NULL ? _cur_vm_operation->name() : _no_op_reason; };
+  static VM_Operation::VMOp_Type vm_op_type()     { return _cur_vm_operation->type(); }
+  static uint64_t get_coalesced_count()           { return _coalesced_count; }
 
   // Returns the single instance of VMThread.
   static VMThread* vm_thread()                    { return _vm_thread; }
--- a/src/hotspot/share/services/diagnosticArgument.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/services/diagnosticArgument.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -180,7 +180,7 @@
     _value = NULL;
   } else {
     _value = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
-    int n = snprintf(_value, len + 1, "%.*s", (int)len, str);
+    int n = os::snprintf(_value, len + 1, "%.*s", (int)len, str);
     assert((size_t)n <= len, "Unexpected number of characters in string");
   }
 }
--- a/src/hotspot/share/services/runtimeService.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/services/runtimeService.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
 #include "logging/log.hpp"
-#include "runtime/timer.hpp"
+#include "logging/logStream.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/attachListener.hpp"
 #include "services/management.hpp"
@@ -35,18 +35,12 @@
 #include "utilities/macros.hpp"
 
 #if INCLUDE_MANAGEMENT
-TimeStamp RuntimeService::_app_timer;
-TimeStamp RuntimeService::_safepoint_timer;
 PerfCounter*  RuntimeService::_sync_time_ticks = NULL;
 PerfCounter*  RuntimeService::_total_safepoints = NULL;
 PerfCounter*  RuntimeService::_safepoint_time_ticks = NULL;
 PerfCounter*  RuntimeService::_application_time_ticks = NULL;
-jlong RuntimeService::_last_safepoint_sync_time_ns = 0;
-jlong RuntimeService::_last_safepoint_end_time_ns = 0;
-jlong RuntimeService::_last_app_time_ns = 0;
 
 void RuntimeService::init() {
-
   if (UsePerfData) {
     EXCEPTION_MARK;
 
@@ -87,85 +81,27 @@
   }
 }
 
-void RuntimeService::record_safepoint_begin() {
+void RuntimeService::record_safepoint_begin(jlong app_ticks) {
   HS_PRIVATE_SAFEPOINT_BEGIN();
-
-  // Print the time interval in which the app was executing
-  if (_app_timer.is_updated()) {
-    _last_app_time_ns = _app_timer.ticks_since_update();
-    log_info(safepoint)("Application time: %3.7f seconds", TimeHelper::counter_to_seconds(_last_app_time_ns));
-  }
-
-  // update the time stamp to begin recording safepoint time
-  _last_safepoint_sync_time_ns = 0;
-  _last_safepoint_end_time_ns = 0;
-  _safepoint_timer.update();
   if (UsePerfData) {
     _total_safepoints->inc();
-    if (_app_timer.is_updated()) {
-      _application_time_ticks->inc(_app_timer.ticks_since_update());
-    }
+    _application_time_ticks->inc(app_ticks);
   }
 }
 
-void RuntimeService::record_safepoint_synchronized() {
+void RuntimeService::record_safepoint_synchronized(jlong sync_ticks) {
   if (UsePerfData) {
-    _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
-  }
-  if (log_is_enabled(Info, safepoint) || log_is_enabled(Info, safepoint, stats)) {
-    _last_safepoint_sync_time_ns = _safepoint_timer.ticks_since_update();
+    _sync_time_ticks->inc(sync_ticks);
   }
 }
 
-void RuntimeService::record_safepoint_end() {
+void RuntimeService::record_safepoint_end(jlong safepoint_ticks) {
   HS_PRIVATE_SAFEPOINT_END();
-
-  // Logging of safepoint+stats=info needs _last_safepoint_end_time_ns to be set.
-  // Logging of safepoint=info needs _last_safepoint_end_time_ns for following log.
-  if (log_is_enabled(Info, safepoint) || log_is_enabled(Info, safepoint, stats)) {
-    _last_safepoint_end_time_ns = _safepoint_timer.ticks_since_update();
-    log_info(safepoint)(
-       "Total time for which application threads were stopped: %3.7f seconds, "
-       "Stopping threads took: %3.7f seconds",
-       TimeHelper::counter_to_seconds(_last_safepoint_end_time_ns),
-       TimeHelper::counter_to_seconds(_last_safepoint_sync_time_ns));
-  }
-
-  // update the time stamp to begin recording app time
-  _app_timer.update();
   if (UsePerfData) {
-    _safepoint_time_ticks->inc(_safepoint_timer.ticks_since_update());
+    _safepoint_time_ticks->inc(safepoint_ticks);
   }
 }
 
-void RuntimeService::record_safepoint_epilog(const char* operation_name) {
-  if (!log_is_enabled(Info, safepoint, stats)) {
-    return;
-  }
-
-  log_info(safepoint, stats)(
-     "Safepoint \"%s\", "
-     "Time since last: " JLONG_FORMAT " ns; "
-     "Reaching safepoint: " JLONG_FORMAT " ns; "
-     "At safepoint: " JLONG_FORMAT " ns; "
-     "Total: " JLONG_FORMAT " ns",
-      operation_name,
-      _last_app_time_ns,
-      _last_safepoint_sync_time_ns,
-      _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns,
-      _last_safepoint_end_time_ns
-     );
-}
-
-void RuntimeService::record_application_start() {
-  // update the time stamp to begin recording app time
-  _app_timer.update();
-}
-
-// Don't need to record application end because we currently
-// exit at a safepoint and record_safepoint_begin() handles updating
-// the application time counter at VM exit.
-
 jlong RuntimeService::safepoint_sync_time_ms() {
   return UsePerfData ?
     Management::ticks_to_ms(_sync_time_ticks->get_value()) : -1;
--- a/src/hotspot/share/services/runtimeService.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/services/runtimeService.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -35,12 +35,6 @@
   static PerfCounter* _safepoint_time_ticks;   // Accumulated time at safepoints
   static PerfCounter* _application_time_ticks; // Accumulated time not at safepoints
 
-  static TimeStamp _safepoint_timer;
-  static TimeStamp _app_timer;
-  static jlong _last_safepoint_sync_time_ns;
-  static jlong _last_safepoint_end_time_ns;
-  static jlong _last_app_time_ns;
-
 public:
   static void init();
 
@@ -50,12 +44,9 @@
   static jlong application_time_ms();
 
   // callbacks
-  static void record_safepoint_begin() NOT_MANAGEMENT_RETURN;
-  static void record_safepoint_synchronized() NOT_MANAGEMENT_RETURN;
-  static void record_safepoint_end() NOT_MANAGEMENT_RETURN;
-  static void record_safepoint_epilog(const char* operation_name) NOT_MANAGEMENT_RETURN;
-  static void record_application_start() NOT_MANAGEMENT_RETURN;
-
+  static void record_safepoint_begin(jlong app_ticks) NOT_MANAGEMENT_RETURN;
+  static void record_safepoint_synchronized(jlong sync_ticks) NOT_MANAGEMENT_RETURN;
+  static void record_safepoint_end(jlong safepoint_ticks) NOT_MANAGEMENT_RETURN;
 };
 
 #endif // SHARE_SERVICES_RUNTIMESERVICE_HPP
--- a/src/hotspot/share/utilities/debug.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/utilities/debug.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -643,6 +643,7 @@
   tty->print_cr("                   pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or");
   tty->print_cr("                   pns($sp, $ebp, $pc) on Linux/x86 or");
   tty->print_cr("                   pns($sp, 0, $pc)    on Linux/ppc64 or");
+  tty->print_cr("                   pns($sp, $s8, $pc)  on Linux/mips or");
   tty->print_cr("                   pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC");
   tty->print_cr("                 - in gdb do 'set overload-resolution off' before calling pns()");
   tty->print_cr("                 - in dbx do 'frame 1' before calling pns()");
--- a/src/hotspot/share/utilities/intHisto.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "utilities/intHisto.hpp"
-
-IntHistogram::IntHistogram(int est, int max) : _max(max), _tot(0) {
-  assert(0 <= est && est <= max, "Preconditions");
-  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(est, true);
-  guarantee(_elements != NULL, "alloc failure");
-}
-
-void IntHistogram::add_entry(int outcome) {
-  if (outcome > _max) outcome = _max;
-  int new_count = _elements->at_grow(outcome) + 1;
-  _elements->at_put(outcome, new_count);
-  _tot++;
-}
-
-int IntHistogram::entries_for_outcome(int outcome) {
-  return _elements->at_grow(outcome);
-}
-
-void IntHistogram::print_on(outputStream* st) const {
-  double tot_d = (double)_tot;
-  st->print_cr("Outcome     # of occurrences   %% of occurrences");
-  st->print_cr("-----------------------------------------------");
-  for (int i=0; i < _elements->length()-2; i++) {
-    int cnt = _elements->at(i);
-    if (cnt != 0) {
-      st->print_cr("%7d        %10d         %8.4f",
-                   i, cnt, (double)cnt/tot_d);
-    }
-  }
-  // Does it have any max entries?
-  if (_elements->length()-1 == _max) {
-    int cnt = _elements->at(_max);
-    st->print_cr(">= %4d        %10d         %8.4f",
-                 _max, cnt, (double)cnt/tot_d);
-  }
-  st->print_cr("-----------------------------------------------");
-  st->print_cr("    All        %10d         %8.4f", _tot, 1.0);
-}
--- a/src/hotspot/share/utilities/intHisto.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_UTILITIES_INTHISTO_HPP
-#define SHARE_UTILITIES_INTHISTO_HPP
-
-#include "memory/allocation.hpp"
-#include "utilities/growableArray.hpp"
-
-// This class implements a simple histogram.
-
-// A histogram summarizes a series of "measurements", each of which is
-// assumed (required in this implementation) to have an outcome that is a
-// non-negative integer.  The histogram efficiently maps measurement outcomes
-// to the number of measurements had that outcome.
-
-// To print the results, invoke print() on your Histogram*.
-
-// Note: there is already an existing "Histogram" class, in file
-// histogram.{hpp,cpp}, but to my mind that's not a histogram, it's a table
-// mapping strings to counts.  To be a histogram (IMHO) it needs to map
-// numbers (in fact, integers) to number of occurrences of that number.
-
-// ysr: (i am not sure i agree with the above note.) i suspect we want to have a
-// histogram template that will map an arbitrary type (with a defined order
-// relation) to a count.
-
-
-class IntHistogram : public CHeapObj<mtInternal> {
- protected:
-  int _max;
-  int _tot;
-  GrowableArray<int>* _elements;
-
-public:
-  // Create a new, empty table.  "est" is an estimate of the maximum outcome
-  // that will be added, and "max" is an outcome such that all outcomes at
-  // least that large will be bundled with it.
-  IntHistogram(int est, int max);
-  // Add a measurement with the given outcome to the sequence.
-  void add_entry(int outcome);
-  // Return the number of entries recorded so far with the given outcome.
-  int  entries_for_outcome(int outcome);
-  // Return the total number of entries recorded so far.
-  int  total_entries() { return _tot; }
-  // Return the number of entries recorded so far with the given outcome as
-  // a fraction of the total number recorded so far.
-  double fraction_for_outcome(int outcome) {
-    return
-      (double)entries_for_outcome(outcome)/
-      (double)total_entries();
-  }
-  // Print the histogram on the given output stream.
-  void print_on(outputStream* st) const;
-};
-
-#endif // SHARE_UTILITIES_INTHISTO_HPP
--- a/src/hotspot/share/utilities/ostream.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/utilities/ostream.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -559,18 +559,6 @@
   fflush(_file);
 }
 
-fdStream::fdStream(const char* file_name) {
-  _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-  _need_close = true;
-}
-
-fdStream::~fdStream() {
-  if (_fd != -1) {
-    if (_need_close) close(_fd);
-    _fd = -1;
-  }
-}
-
 void fdStream::write(const char* s, size_t len) {
   if (_fd != -1) {
     // Make an unused local variable to avoid warning from gcc 4.x compiler.
--- a/src/hotspot/share/utilities/ostream.hpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/utilities/ostream.hpp	Thu Feb 28 22:05:33 2019 +0100
@@ -216,7 +216,6 @@
   fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
   ~fileStream();
   bool is_open() const { return _file != NULL; }
-  void set_need_close(bool b) { _need_close = b;}
   virtual void write(const char* c, size_t len);
   size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); }
   char* readln(char *data, int count);
@@ -235,13 +234,10 @@
 class fdStream : public outputStream {
  protected:
   int  _fd;
-  bool _need_close;
  public:
-  fdStream(const char* file_name);
-  fdStream(int fd = -1) { _fd = fd; _need_close = false; }
-  ~fdStream();
+  fdStream(int fd = -1) : _fd(fd) { }
   bool is_open() const { return _fd != -1; }
-  void set_fd(int fd) { _fd = fd; _need_close = false; }
+  void set_fd(int fd) { _fd = fd; }
   int fd() const { return _fd; }
   virtual void write(const char* c, size_t len);
   void flush() {};
--- a/src/hotspot/share/utilities/xmlstream.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/hotspot/share/utilities/xmlstream.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -356,11 +356,11 @@
   size_t kind_len;
   if (kind_end != NULL) {
     kind_len = kind_end - kind;
-    int n = snprintf(buffer, sizeof(buffer), "%.*s_done", (int)kind_len, kind);
+    int n = os::snprintf(buffer, sizeof(buffer), "%.*s_done", (int)kind_len, kind);
     assert((size_t)n < sizeof(buffer), "Unexpected number of characters in string");
   } else {
     kind_len = format_len;
-    int n = snprintf(buffer, sizeof(buffer), "%s_done%s", kind, kind + kind_len);
+    int n = os::snprintf(buffer, sizeof(buffer), "%s_done%s", kind, kind + kind_len);
     assert((size_t)n < sizeof(buffer), "Unexpected number of characters in string");
   }
   // Output the trailing event with the timestamp.
--- a/src/java.base/macosx/native/libjli/java_md_macosx.m	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/macosx/native/libjli/java_md_macosx.m	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -717,10 +717,17 @@
 }
 
 /*
- * Block current thread and continue execution in a new thread
+ * Signature adapter for pthread_create().
+ */
+static void* ThreadJavaMain(void* args) {
+    return (void*)(intptr_t)JavaMain(args);
+}
+
+/*
+ * Block current thread and continue execution in a new thread.
  */
 int
-ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
+CallJavaMainInNewThread(jlong stack_size, void* args) {
     int rslt;
     pthread_t tid;
     pthread_attr_t attr;
@@ -728,22 +735,22 @@
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
     if (stack_size > 0) {
-      pthread_attr_setstacksize(&attr, stack_size);
+        pthread_attr_setstacksize(&attr, stack_size);
     }
     pthread_attr_setguardsize(&attr, 0); // no pthread guard page on java threads
 
-    if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
-      void * tmp;
-      pthread_join(tid, &tmp);
-      rslt = (int)(intptr_t)tmp;
+    if (pthread_create(&tid, &attr, ThreadJavaMain, args) == 0) {
+        void* tmp;
+        pthread_join(tid, &tmp);
+        rslt = (int)(intptr_t)tmp;
     } else {
-     /*
-      * Continue execution in current thread if for some reason (e.g. out of
-      * memory/LWP)  a new thread can't be created. This will likely fail
-      * later in continuation as JNI_CreateJavaVM needs to create quite a
-      * few new threads, anyway, just give it a try..
-      */
-      rslt = continuation(args);
+       /*
+        * Continue execution in current thread if for some reason (e.g. out of
+        * memory/LWP)  a new thread can't be created. This will likely fail
+        * later in JavaMain as JNI_CreateJavaVM needs to create quite a
+        * few new threads, anyway, just give it a try..
+        */
+        rslt = JavaMain(args);
     }
 
     pthread_attr_destroy(&attr);
--- a/src/java.base/share/classes/java/lang/Throwable.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Throwable.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -616,7 +616,7 @@
      *          ... 1 more
      * </pre>
      * Note that the "... n more" notation is used on suppressed exceptions
-     * just at it is used on causes. Unlike causes, suppressed exceptions are
+     * just as it is used on causes. Unlike causes, suppressed exceptions are
      * indented beyond their "containing exceptions."
      *
      * <p>An exception can have both a cause and one or more suppressed
--- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java	Thu Feb 28 22:05:33 2019 +0100
@@ -170,7 +170,7 @@
      *
      * @param rank the rank of the array
      * @return a {@linkplain ClassDesc} describing the array type
-     * @throws IllegalArgumentException if the rank is less than zero or if the rank of the resulting array type is
+     * @throws IllegalArgumentException if the rank is less than or equal to zero or if the rank of the resulting array type is
      * greater than 255
      * @jvms 4.4.1 The CONSTANT_Class_info Structure
      */
--- a/src/java.base/share/classes/java/nio/Bits.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/Bits.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -172,7 +172,10 @@
             }
 
             // no luck
-            throw new OutOfMemoryError("Direct buffer memory");
+            throw new OutOfMemoryError
+                ("Cannot reserve "
+                 + size + " bytes of direct buffer memory (allocated: "
+                 + RESERVED_MEMORY.get() + ", limit: " + MAX_MEMORY +")");
 
         } finally {
             if (interrupted) {
--- a/src/java.base/share/classes/java/nio/Buffer.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/Buffer.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -134,8 +134,9 @@
  *   it already contains: It leaves the limit unchanged and sets the position
  *   to zero.  </p></li>
  *
- *   <li><p> {@link #slice} creates a subsequence of a buffer: It leaves the
- *   limit and the position unchanged. </p></li>
+ *   <li><p> The {@link #slice} and {@link #slice(int,int) slice(index,length)}
+ *   methods create a subsequence of a buffer: They leave the limit and the
+ *   position unchanged. </p></li>
  *
  *   <li><p> {@link #duplicate} creates a shallow copy of a buffer: It leaves
  *   the limit and the position unchanged. </p></li>
@@ -600,6 +601,39 @@
     public abstract Buffer slice();
 
     /**
+     * Creates a new buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at position {@code index}
+     * in this buffer, and will contain {@code length} elements. Changes to
+     * this buffer's content will be visible in the new buffer, and vice versa;
+     * the two buffers' position, limit, and mark values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be {@code length}, its mark will be undefined. The new buffer will
+     * be direct if, and only if, this buffer is direct, and it will be
+     * read-only if, and only if, this buffer is read-only.  </p>
+     *
+     * @param   index
+     *          The position in this buffer at which the content of the new
+     *          buffer will start; must be non-negative and no larger than
+     *          {@link #limit() limit()}
+     *
+     * @param   length
+     *          The number of elements the new buffer will contain; must be
+     *          non-negative and no larger than {@code limit() - index}
+     *
+     * @return  The new buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If {@code index} is negative or greater than {@code limit()},
+     *          {@code length} is negative, or {@code length > limit() - index}
+     *
+     * @since 13
+     */
+    public abstract Buffer slice(int index, int length);
+
+    /**
      * Creates a new buffer that shares this buffer's content.
      *
      * <p> The content of the new buffer will be that of this buffer.  Changes
--- a/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,9 @@
 
 package java.nio;
 
+import java.util.Objects;
 import jdk.internal.misc.Unsafe;
 
-
 class ByteBufferAs$Type$Buffer$RW$$BO$                  // package-private
     extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$}
 {
@@ -85,6 +85,18 @@
         return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, addr);
     }
 
+    @Override
+    public $Type$Buffer slice(int index, int length) {
+        Objects.checkIndex(index, limit() + 1);
+        Objects.checkIndex(length, limit() - index + 1);
+        return new ByteBufferAs$Type$Buffer$RW$$BO$(bb,
+                                                    -1,
+                                                    0,
+                                                    length,
+                                                    length,
+                                                    byteOffset(index));
+    }
+
     public $Type$Buffer duplicate() {
         return new ByteBufferAs$Type$Buffer$RW$$BO$(bb,
                                                     this.markValue(),
--- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Thu Feb 28 22:05:33 2019 +0100
@@ -218,14 +218,17 @@
         return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
     }
 
-#if[byte]
-    public $Type$Buffer slice(int pos, int lim) {
-        assert (pos >= 0);
-        assert (pos <= lim);
-        int rem = lim - pos;
-        return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, pos);
+    @Override
+    public $Type$Buffer slice(int index, int length) {
+        Objects.checkIndex(index, limit() + 1);
+        Objects.checkIndex(length, limit() - index + 1);
+        return new Direct$Type$Buffer$RW$$BO$(this,
+                                              -1,
+                                              0,
+                                              length,
+                                              length,
+                                              index);
     }
-#end[byte]
 
     public $Type$Buffer duplicate() {
         return new Direct$Type$Buffer$RW$$BO$(this,
--- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template	Thu Feb 28 22:05:33 2019 +0100
@@ -27,6 +27,8 @@
 
 package java.nio;
 
+import java.util.Objects;
+
 /**
 #if[rw]
  * A read/write Heap$Type$Buffer.
@@ -38,8 +40,6 @@
 #end[rw]
  */
 
-import java.util.Objects;
-
 class Heap$Type$Buffer$RW$
     extends {#if[ro]?Heap}$Type$Buffer
 {
@@ -112,19 +112,17 @@
                                         this.position() + offset);
     }
 
-#if[byte]
-    $Type$Buffer slice(int pos, int lim) {
-        assert (pos >= 0);
-        assert (pos <= lim);
-        int rem = lim - pos;
+    @Override
+    public $Type$Buffer slice(int index, int length) {
+        Objects.checkIndex(index, limit() + 1);
+        Objects.checkIndex(length, limit() - index + 1);
         return new Heap$Type$Buffer$RW$(hb,
                                         -1,
                                         0,
-                                        rem,
-                                        rem,
-                                        pos + offset);
+                                        length,
+                                        length,
+                                        index + offset);
     }
-#end[byte]
 
     public $Type$Buffer duplicate() {
         return new Heap$Type$Buffer$RW$(hb,
@@ -270,6 +268,25 @@
 #end[rw]
     }
 
+#if[char]
+
+    public $Type$Buffer put(String src, int start, int end) {
+        int length = end - start;
+        checkBounds(start, length, src.length());
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int pos = position();
+        int lim = limit();
+        int rem = (pos <= lim) ? lim - pos : 0;
+        if (length > rem)
+            throw new BufferOverflowException();
+        src.getChars(start, end, hb, ix(pos));
+        position(pos + length);
+        return this;
+    }
+
+#end[char]
+
     public $Type$Buffer compact() {
 #if[rw]
         System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
--- a/src/java.base/share/classes/java/nio/StringCharBuffer.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/StringCharBuffer.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package java.nio;
 
+import java.util.Objects;
 
 // ## If the sequence is a string, use reflection to share its array
 
@@ -51,6 +52,18 @@
                                     offset + this.position());
     }
 
+    @Override
+    public CharBuffer slice(int index, int length) {
+        Objects.checkIndex(index, limit() + 1);
+        Objects.checkIndex(length, limit() - index + 1);
+        return new StringCharBuffer(str,
+                                    -1,
+                                    0,
+                                    length,
+                                    length,
+                                    offset + index);
+    }
+
     private StringCharBuffer(CharSequence s,
                              int mark,
                              int pos,
--- a/src/java.base/share/classes/java/nio/X-Buffer.java.template	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template	Thu Feb 28 22:05:33 2019 +0100
@@ -547,6 +547,46 @@
     public abstract $Type$Buffer slice();
 
     /**
+     * Creates a new $type$ buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at position {@code index}
+     * in this buffer, and will contain {@code length} elements. Changes to
+     * this buffer's content will be visible in the new buffer, and vice versa;
+     * the two buffers' position, limit, and mark values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be {@code length}, its mark will be undefined, and its byte order
+     * will be
+#if[byte]
+     * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+#else[byte]
+     * identical to that of this buffer.
+#end[byte]
+     * The new buffer will be direct if, and only if, this buffer is direct,
+     * and it will be read-only if, and only if, this buffer is read-only. </p>
+     *
+     * @param   index
+     *          The position in this buffer at which the content of the new
+     *          buffer will start; must be non-negative and no larger than
+     *          {@link #limit() limit()}
+     *
+     * @param   length
+     *          The number of elements the new buffer will contain; must be
+     *          non-negative and no larger than {@code limit() - index}
+     *
+     * @return  The new buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If {@code index} is negative or greater than {@code limit()},
+     *          {@code length} is negative, or {@code length > limit() - index}
+     *
+     * @since 13
+     */
+    @Override
+    public abstract $Type$Buffer slice(int index, int length);
+
+    /**
      * Creates a new $type$ buffer that shares this buffer's content.
      *
      * <p> The content of the new buffer will be that of this buffer.  Changes
@@ -1950,11 +1990,9 @@
             aligned_pos = aligned_lim = pos;
         }
 
-        return slice(aligned_pos, aligned_lim);
+        return slice(aligned_pos, aligned_lim - aligned_pos);
     }
 
-    abstract ByteBuffer slice(int pos, int lim);
-
     // #BIN
     //
     // Binary-data access methods  for short, char, int, long, float,
--- a/src/java.base/share/classes/java/security/PrivilegedAction.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/security/PrivilegedAction.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
  * @see AccessController#doPrivileged(PrivilegedAction)
  * @see PrivilegedExceptionAction
  */
-
+@FunctionalInterface
 public interface PrivilegedAction<T> {
     /**
      * Performs the computation.  This method will be called by
--- a/src/java.base/share/classes/java/security/PrivilegedExceptionAction.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/security/PrivilegedExceptionAction.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
  *                                              AccessControlContext)
  * @see PrivilegedAction
  */
-
+@FunctionalInterface
 public interface PrivilegedExceptionAction<T> {
     /**
      * Performs the computation.  This method will be called by
--- a/src/java.base/share/classes/java/util/spi/ToolProvider.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/java/util/spi/ToolProvider.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,8 +126,9 @@
     default int run(PrintStream out, PrintStream err, String... args) {
         Objects.requireNonNull(out);
         Objects.requireNonNull(err);
+        Objects.requireNonNull(args);
         for (String arg : args) {
-            Objects.requireNonNull(args);
+            Objects.requireNonNull(arg);
         }
 
         PrintWriter outWriter = new PrintWriter(out);
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3114,7 +3114,7 @@
      * @param offset field/element offset
      * @param mask the mask value
      * @return the previous value
-     * @since 1.9
+     * @since 9
      */
     @ForceInline
     public final int getAndBitwiseAndInt(Object o, long offset, int mask) {
@@ -3343,6 +3343,14 @@
     }
 
     /**
+     * Throws NoSuchMethodError; for use by the VM for redefinition support.
+     * @since 13
+     */
+    private static void throwNoSuchMethodError() {
+        throw new NoSuchMethodError();
+    }
+
+    /**
      * @return Returns true if the native byte ordering of this
      * platform is big-endian, false if it is little-endian.
      */
--- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -175,7 +175,7 @@
     public FieldAccessor newFieldAccessor(Field field, boolean override) {
         checkInitted();
 
-        Field root = langReflectAccess.getRoot(field);
+        Field root = langReflectAccess().getRoot(field);
         if (root != null) {
             // FieldAccessor will use the root unless the modifiers have
             // been overrridden
@@ -197,7 +197,7 @@
         }
 
         // use the root Method that will not cache caller class
-        Method root = langReflectAccess.getRoot(method);
+        Method root = langReflectAccess().getRoot(method);
         if (root != null) {
             method = root;
         }
@@ -233,7 +233,7 @@
         }
 
         // use the root Constructor that will not cache caller class
-        Constructor<?> root = langReflectAccess.getRoot(c);
+        Constructor<?> root = langReflectAccess().getRoot(c);
         if (root != null) {
             c = root;
         }
--- a/src/java.base/share/classes/sun/security/ssl/Finished.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/Finished.java	Thu Feb 28 22:05:33 2019 +0100
@@ -102,7 +102,7 @@
             }
 
             if (m.remaining() != verifyDataLen) {
-                throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
+                throw context.conContext.fatal(Alert.DECODE_ERROR,
                     "Inappropriate finished message: need " + verifyDataLen +
                     " but remaining " + m.remaining() + " bytes verify_data");
             }
@@ -120,7 +120,7 @@
                         "Failed to generate verify_data", ioe);
             }
             if (!MessageDigest.isEqual(myVerifyData, verifyData)) {
-                throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
+                throw context.conContext.fatal(Alert.DECRYPT_ERROR,
                         "The Finished message cannot be verified.");
             }
         }
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -916,8 +916,12 @@
         /**
          * Try the best to use up the input records so as to close the
          * socket gracefully, without impact the performance too much.
+         *
+         * Note: please don't synchronize this method as the read() method
+         * may hold the lock. A race should be fine as this method is
+         * designed for cleanup only.
          */
-        private synchronized void deplete() {
+        private void deplete() {
             if (!conContext.isInboundClosed()) {
                 if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
                     return;
--- a/src/java.base/share/native/libjli/java.c	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/native/libjli/java.c	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -388,8 +388,8 @@
     } while (JNI_FALSE)
 
 
-int JNICALL
-JavaMain(void * _args)
+int
+JavaMain(void* _args)
 {
     JavaMainArgs *args = (JavaMainArgs *)_args;
     int argc = args->argc;
@@ -2348,7 +2348,7 @@
       args.what = what;
       args.ifn = *ifn;
 
-      rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args);
+      rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args);
       /* If the caller has deemed there is an error we
        * simply return that, otherwise we return the value of
        * the callee
--- a/src/java.base/share/native/libjli/java.h	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/share/native/libjli/java.h	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,10 +156,9 @@
 void PrintMachineDependentOptions();
 
 /*
- * Block current thread and continue execution in new thread
+ * Block current thread and continue execution in new thread.
  */
-int ContinueInNewThread0(int (JNICALL *continuation)(void *),
-                        jlong stack_size, void * args);
+int CallJavaMainInNewThread(jlong stack_size, void* args);
 
 /* sun.java.launcher.* platform properties. */
 void SetJavaLauncherPlatformProps(void);
@@ -224,7 +223,10 @@
 jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
 jclass GetLauncherHelperClass(JNIEnv *env);
 
-int JNICALL JavaMain(void * args); /* entry point                  */
+/*
+ * Entry point.
+ */
+int JavaMain(void* args);
 
 enum LaunchMode {               // cf. sun.launcher.LauncherHelper
     LM_UNKNOWN = 0,
--- a/src/java.base/unix/native/libjli/java_md_solinux.c	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/unix/native/libjli/java_md_solinux.c	Thu Feb 28 22:05:33 2019 +0100
@@ -718,10 +718,17 @@
 }
 
 /*
- * Block current thread and continue execution in a new thread
+ * Signature adapter for pthread_create() or thr_create().
+ */
+static void* ThreadJavaMain(void* args) {
+    return (void*)(intptr_t)JavaMain(args);
+}
+
+/*
+ * Block current thread and continue execution in a new thread.
  */
 int
-ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
+CallJavaMainInNewThread(jlong stack_size, void* args) {
     int rslt;
 #ifndef __solaris__
     pthread_t tid;
@@ -730,35 +737,35 @@
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
     if (stack_size > 0) {
-      pthread_attr_setstacksize(&attr, stack_size);
+        pthread_attr_setstacksize(&attr, stack_size);
     }
     pthread_attr_setguardsize(&attr, 0); // no pthread guard page on java threads
 
-    if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
-      void * tmp;
-      pthread_join(tid, &tmp);
-      rslt = (int)(intptr_t)tmp;
+    if (pthread_create(&tid, &attr, ThreadJavaMain, args) == 0) {
+        void* tmp;
+        pthread_join(tid, &tmp);
+        rslt = (int)(intptr_t)tmp;
     } else {
-     /*
-      * Continue execution in current thread if for some reason (e.g. out of
-      * memory/LWP)  a new thread can't be created. This will likely fail
-      * later in continuation as JNI_CreateJavaVM needs to create quite a
-      * few new threads, anyway, just give it a try..
-      */
-      rslt = continuation(args);
+       /*
+        * Continue execution in current thread if for some reason (e.g. out of
+        * memory/LWP)  a new thread can't be created. This will likely fail
+        * later in JavaMain as JNI_CreateJavaVM needs to create quite a
+        * few new threads, anyway, just give it a try..
+        */
+        rslt = JavaMain(args);
     }
 
     pthread_attr_destroy(&attr);
 #else /* __solaris__ */
     thread_t tid;
     long flags = 0;
-    if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
-      void * tmp;
-      thr_join(tid, NULL, &tmp);
-      rslt = (int)(intptr_t)tmp;
+    if (thr_create(NULL, stack_size, ThreadJavaMain, args, flags, &tid) == 0) {
+        void* tmp;
+        thr_join(tid, NULL, &tmp);
+        rslt = (int)(intptr_t)tmp;
     } else {
-      /* See above. Continue in current thread if thr_create() failed */
-      rslt = continuation(args);
+        /* See above. Continue in current thread if thr_create() failed */
+        rslt = JavaMain(args);
     }
 #endif /* !__solaris__ */
     return rslt;
--- a/src/java.base/windows/native/libjli/java_md.c	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.base/windows/native/libjli/java_md.c	Thu Feb 28 22:05:33 2019 +0100
@@ -704,10 +704,17 @@
 }
 
 /*
- * Block current thread and continue execution in a new thread
+ * Signature adapter for _beginthreadex().
+ */
+static unsigned __stdcall ThreadJavaMain(void* args) {
+    return (unsigned)JavaMain(args);
+}
+
+/*
+ * Block current thread and continue execution in a new thread.
  */
 int
-ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
+CallJavaMainInNewThread(jlong stack_size, void* args) {
     int rslt = 0;
     unsigned thread_id;
 
@@ -722,20 +729,20 @@
      * source (os_win32.cpp) for details.
      */
     HANDLE thread_handle =
-      (HANDLE)_beginthreadex(NULL,
-                             (unsigned)stack_size,
-                             continuation,
-                             args,
-                             STACK_SIZE_PARAM_IS_A_RESERVATION,
-                             &thread_id);
+        (HANDLE)_beginthreadex(NULL,
+                               (unsigned)stack_size,
+                               ThreadJavaMain,
+                               args,
+                               STACK_SIZE_PARAM_IS_A_RESERVATION,
+                               &thread_id);
     if (thread_handle == NULL) {
-      thread_handle =
-      (HANDLE)_beginthreadex(NULL,
-                             (unsigned)stack_size,
-                             continuation,
-                             args,
-                             0,
-                             &thread_id);
+        thread_handle =
+        (HANDLE)_beginthreadex(NULL,
+                               (unsigned)stack_size,
+                               ThreadJavaMain,
+                               args,
+                               0,
+                               &thread_id);
     }
 
     /* AWT preloading (AFTER main thread start) */
@@ -772,11 +779,11 @@
 #endif /* ENABLE_AWT_PRELOAD */
 
     if (thread_handle) {
-      WaitForSingleObject(thread_handle, INFINITE);
-      GetExitCodeThread(thread_handle, &rslt);
-      CloseHandle(thread_handle);
+        WaitForSingleObject(thread_handle, INFINITE);
+        GetExitCodeThread(thread_handle, &rslt);
+        CloseHandle(thread_handle);
     } else {
-      rslt = continuation(args);
+        rslt = JavaMain(args);
     }
 
 #ifdef ENABLE_AWT_PRELOAD
--- a/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,7 @@
  * @author Joseph D. Darcy
  * @author Scott Seligman
  * @author Peter von der Ah&eacute;
+ * @see javax.lang.model.util.Elements
  * @since 1.6
  */
 package javax.lang.model.element;
--- a/src/java.compiler/share/classes/javax/lang/model/type/package-info.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/type/package-info.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
  * @author Joseph D. Darcy
  * @author Scott Seligman
  * @author Peter von der Ah&eacute;
+ * @see javax.lang.model.util.Types
  * @since 1.6
  */
 package javax.lang.model.type;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.h	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.h	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
     jint preFullScreenLevel;
     NSRect standardFrame;
     BOOL isMinimizing;
+    BOOL keyNotificationRecd;
 }
 
 // An instance of either AWTWindow_Normal or AWTWindow_Panel
@@ -62,6 +63,7 @@
 @property (nonatomic) jint preFullScreenLevel;
 @property (nonatomic) NSRect standardFrame;
 @property (nonatomic) BOOL isMinimizing;
+@property (nonatomic) BOOL keyNotificationRecd;
 
 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
                   ownerWindow:owner
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m	Thu Feb 28 22:05:33 2019 +0100
@@ -186,6 +186,7 @@
 @synthesize preFullScreenLevel;
 @synthesize standardFrame;
 @synthesize isMinimizing;
+@synthesize keyNotificationRecd;
 
 - (void) updateMinMaxSize:(BOOL)resizable {
     if (resizable) {
@@ -319,6 +320,7 @@
     if (self.nsWindow == nil) return nil; // no hope either
     [self.nsWindow release]; // the property retains the object already
 
+    self.keyNotificationRecd = NO;
     self.isEnabled = YES;
     self.isMinimizing = NO;
     self.javaPlatformWindow = platformWindow;
@@ -747,9 +749,16 @@
 AWT_ASSERT_APPKIT_THREAD;
     [AWTToolkit eventCountPlusPlus];
 #ifdef DEBUG
-    NSLog(@"became main: %d %@ %@", [self.nsWindow isKeyWindow], [self.nsWindow title], [self menuBarForWindow]);
+    NSLog(@"became main: %d %@ %@ %d", [self.nsWindow isKeyWindow], [self.nsWindow title], [self menuBarForWindow], self.keyNotificationRecd);
 #endif
 
+    // if for some reason, no KEY notification is received but this main window is also a key window
+    // then we need to execute the KEY notification functionality.
+    if(self.keyNotificationRecd != YES && [self.nsWindow isKeyWindow]) {
+        [self doWindowDidBecomeKey];
+    }
+    self.keyNotificationRecd = NO;
+
     if (![self.nsWindow isKeyWindow]) {
         [self activateWindowMenuBar];
     }
@@ -769,6 +778,12 @@
 #ifdef DEBUG
     NSLog(@"became key: %d %@ %@", [self.nsWindow isMainWindow], [self.nsWindow title], [self menuBarForWindow]);
 #endif
+    [self doWindowDidBecomeKey];
+    self.keyNotificationRecd = YES;
+}
+
+- (void) doWindowDidBecomeKey {
+AWT_ASSERT_APPKIT_THREAD;
     AWTWindow *opposite = [AWTWindow lastKeyWindow];
 
     if (![self.nsWindow isMainWindow]) {
--- a/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1362,6 +1362,19 @@
         } else {
             digits = value;
         }
+        // Some webpage passes 3 digit color code as in #fff which is
+        // decoded as #000FFF resulting in blue background.
+        // As per https://www.w3.org/TR/CSS1/#color-units,
+        // The three-digit RGB notation (#rgb) is converted into six-digit form
+        // (#rrggbb) by replicating digits, not by adding zeros.
+        // This makes sure that white (#ffffff) can be specified with the short notation
+        // (#fff) and removes any dependencies on the color depth of the display.
+        if (digits.length() == 3) {
+            final String r = digits.substring(0, 1);
+            final String g = digits.substring(1, 2);
+            final String b = digits.substring(2, 3);
+            digits = String.format("%s%s%s%s%s%s", r, r, g, g, b, b);
+        }
         String hstr = "0x" + digits;
         Color c;
         try {
--- a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java	Thu Feb 28 22:05:33 2019 +0100
@@ -1185,6 +1185,10 @@
             parserState.put(keyword, Integer.valueOf(parameter));
             return true;
         }
+        if (keyword.equals("cb")) {
+            parserState.put(keyword, Integer.valueOf(parameter));
+            return true;
+        }
 
         {
             RTFAttribute attr = straightforwardAttributes.get(keyword);
--- a/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Thu Feb 28 22:05:33 2019 +0100
@@ -403,18 +403,36 @@
        list.
     */
     class RemotePrinterChangeListener implements Runnable {
-        private String[] prevRemotePrinters;
+        private String[] prevRemotePrinters = null;
 
         RemotePrinterChangeListener() {
             prevRemotePrinters = getRemotePrintersNames();
         }
 
         boolean doCompare(String[] str1, String[] str2) {
+            if (str1 == null && str2 == null) {
+                return false;
+            } else if (str1 == null || str2 == null) {
+                return true;
+            }
+
             if (str1.length != str2.length) {
                 return true;
             } else {
                 for (int i = 0;i < str1.length;i++) {
                     for (int j = 0;j < str2.length;j++) {
+                        // skip if both are nulls
+                        if (str1[i] == null && str2[j] == null) {
+                            continue;
+                        }
+
+                        // return true if there is a 'difference' but
+                        // no need to access the individual string
+                        if (str1[i] == null || str2[j] == null) {
+                            return true;
+                        }
+
+                        // do comparison only if they are non-nulls
                         if (!str1[i].equals(str2[j])) {
                             return true;
                         }
@@ -428,15 +446,19 @@
         @Override
         public void run() {
             while (true) {
-                String[] currentRemotePrinters = getRemotePrintersNames();
-                if (doCompare(prevRemotePrinters, currentRemotePrinters)) {
+                if (prevRemotePrinters != null && prevRemotePrinters.length > 0) {
+                    String[] currentRemotePrinters = getRemotePrintersNames();
+                    if (doCompare(prevRemotePrinters, currentRemotePrinters)) {
 
-                    // updated the printers data
-                    // printers list now contains both local and network printer data
-                    refreshServices();
+                        // updated the printers data
+                        // printers list now contains both local and network printer data
+                        refreshServices();
 
-                    // store the current data for next comparison
-                    prevRemotePrinters = currentRemotePrinters;
+                        // store the current data for next comparison
+                        prevRemotePrinters = currentRemotePrinters;
+                    }
+                } else {
+                    prevRemotePrinters = getRemotePrintersNames();
                 }
 
                 try {
--- a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp	Thu Feb 28 22:05:33 2019 +0100
@@ -249,7 +249,7 @@
     if (clazz == NULL) {
         return NULL;
     }
-    jobjectArray nameArray;
+    jobjectArray nameArray = NULL;
 
     try {
         ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
@@ -270,13 +270,14 @@
                 }
             }
 
-            // Allocate space only for the network type printers
-            nameArray = env->NewObjectArray(remotePrintersCount, clazz, NULL);
-            if (nameArray == NULL) {
-                throw std::bad_alloc();
+            // return remote printers only if the list contains it.
+            if (remotePrintersCount > 0) {
+                // Allocate space only for the network type printers
+                nameArray = env->NewObjectArray(remotePrintersCount, clazz, NULL);
+                if (nameArray == NULL) {
+                    throw std::bad_alloc();
+                }
             }
-        } else {
-            nameArray = NULL;
         }
 
         // Loop thro' network printers list only
@@ -298,7 +299,12 @@
 
     delete [] pPrinterEnum;
     delete [] pNetworkPrinterLoc;
-    return nameArray;
+
+    if (nameArray != NULL) {
+      return nameArray;
+    } else {
+      return env->NewObjectArray(0, clazz, NULL);
+    }
 
     CATCH_BAD_ALLOC_RET(NULL);
 }
--- a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c	Thu Feb 28 22:05:33 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -181,7 +181,7 @@
 {
     SCARDCONTEXT context = (SCARDCONTEXT)jContext;
     LONG rv;
-    LPTSTR mszReaders = NULL;
+    LPSTR mszReaders = NULL;
     DWORD size = 0;
     jobjectArray result;
 
@@ -220,7 +220,7 @@
 {
     SCARDCONTEXT context = (SCARDCONTEXT)jContext;
     LONG rv;
-    LPCTSTR readerName;
+    LPCSTR readerName;
     SCARDHANDLE card = 0;
     DWORD proto = 0;
 
--- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING	Fri Feb 22 14:51:06 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-Copyright (c) 1999-2003 David Corcoran <corcoran@linuxnet.com>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-Changes to this license can be made only by the copyright author with 
-explicit written consent.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h	Fri Feb 22 14:51:06 2019 +0100
+++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h	Thu Feb 28 22:05:33 2019 +0100
@@ -1,374 +1,306 @@
 /*
- * This keeps a list of defines for pcsc-lite.
- *
- * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
  *
  * Copyright (C) 1999-2004
- *  David Corcoran <corcoran@linuxnet.com>
+ *  David Corcoran <corcoran@musclecard.com>
+ * Copyright (C) 2002-2011
  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
+ * Copyright (C) 2005
+ *  Martin Paljak <martin@paljak.pri.ee>
  *
- * $Id: pcsclite.h.in,v 1.47 2004/08/24 21:46:57 rousseau Exp $
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of defines for pcsc-lite.
+ *
+ * Error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
  */
 
 #ifndef __pcsclite_h__
 #define __pcsclite_h__
 
-#ifndef __sun_jdk
 #include <wintypes.h>
-#else
-#include <sys/types.h>
-#include <inttypes.h>
-#ifdef BYTE
-#error BYTE is already defined
-#else
-  typedef unsigned char BYTE;
-#endif /* End BYTE */
-
-        typedef unsigned char UCHAR;
-        typedef unsigned char *PUCHAR;
-        typedef unsigned short USHORT;
-        typedef unsigned long ULONG;
-        typedef void *LPVOID;
-        typedef short BOOL;
-        typedef unsigned long *PULONG;
-        typedef const void *LPCVOID;
-        typedef unsigned long DWORD;
-        typedef unsigned long *PDWORD;
-        typedef unsigned short WORD;
-        typedef long LONG;
-        typedef long RESPONSECODE;
-        typedef const char *LPCTSTR;
-        typedef const BYTE *LPCBYTE;
-        typedef BYTE *LPBYTE;
-        typedef DWORD *LPDWORD;
-        typedef char *LPTSTR;
-
-#endif
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
-#ifdef WIN32
-#include <winscard.h>
-#else
-typedef long SCARDCONTEXT;
+typedef LONG SCARDCONTEXT; /**< \p hContext returned by SCardEstablishContext() */
 typedef SCARDCONTEXT *PSCARDCONTEXT;
 typedef SCARDCONTEXT *LPSCARDCONTEXT;
-typedef long SCARDHANDLE;
+typedef LONG SCARDHANDLE; /**< \p hCard returned by SCardConnect() */
 typedef SCARDHANDLE *PSCARDHANDLE;
 typedef SCARDHANDLE *LPSCARDHANDLE;
 
-#define MAX_ATR_SIZE                    33      /* Maximum ATR size */
+#define MAX_ATR_SIZE                  33      /**< Maximum ATR size */
 
-#ifndef __APPLE__
+/* Set structure elements aligment on bytes
+ * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
+#ifdef __APPLE__
+#pragma pack(1)
+#endif
 
 typedef struct
 {
-        const char *szReader;
-        void *pvUserData;
-        unsigned long dwCurrentState;
-        unsigned long dwEventState;
-        unsigned long cbAtr;
-        unsigned char rgbAtr[MAX_ATR_SIZE];
+      const char *szReader;
+      void *pvUserData;
+      DWORD dwCurrentState;
+      DWORD dwEventState;
+      DWORD cbAtr;
+      unsigned char rgbAtr[MAX_ATR_SIZE];
 }
-SCARD_READERSTATE_A;
+SCARD_READERSTATE, *LPSCARD_READERSTATE;
 
-typedef struct _SCARD_IO_REQUEST
+/** Protocol Control Information (PCI) */
+typedef struct
 {
-        unsigned long dwProtocol;       /* Protocol identifier */
-        unsigned long cbPciLength;      /* Protocol Control Inf Length */
+      unsigned long dwProtocol;      /**< Protocol identifier */
+      unsigned long cbPciLength;      /**< Protocol Control Inf Length */
 }
 SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
 
-#else // __APPLE__
-
-#pragma pack(1)
-typedef struct
-{
-        const char *szReader;
-        void *pvUserData;
-        uint32_t dwCurrentState;
-        uint32_t dwEventState;
-        uint32_t cbAtr;
-        unsigned char rgbAtr[MAX_ATR_SIZE];
-}
-SCARD_READERSTATE_A;
-
-typedef struct _SCARD_IO_REQUEST
-{
-        uint32_t dwProtocol;            /* Protocol identifier */
-        uint32_t cbPciLength;           /* Protocol Control Inf Length */
-}
-SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
-#pragma pack()
-
-#endif // __APPLE__
-
-typedef SCARD_READERSTATE_A SCARD_READERSTATE, *PSCARD_READERSTATE_A,
-        *LPSCARD_READERSTATE_A;
-
 typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;
 
-extern SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci,
-        g_rgSCardRawPci;
+extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci;
 
-#define SCARD_PCI_T0    (&g_rgSCardT0Pci)
-#define SCARD_PCI_T1    (&g_rgSCardT1Pci)
-#define SCARD_PCI_RAW   (&g_rgSCardRawPci)
-
-#define SCARD_S_SUCCESS                 0x00000000
-#define SCARD_E_CANCELLED               0x80100002
-#define SCARD_E_CANT_DISPOSE            0x8010000E
-#define SCARD_E_INSUFFICIENT_BUFFER     0x80100008
-#define SCARD_E_INVALID_ATR             0x80100015
-#define SCARD_E_INVALID_HANDLE          0x80100003
-#define SCARD_E_INVALID_PARAMETER       0x80100004
-#define SCARD_E_INVALID_TARGET          0x80100005
-#define SCARD_E_INVALID_VALUE           0x80100011
-#define SCARD_E_NO_MEMORY               0x80100006
-#define SCARD_F_COMM_ERROR              0x80100013
-#define SCARD_F_INTERNAL_ERROR          0x80100001
-#define SCARD_F_UNKNOWN_ERROR           0x80100014
-#define SCARD_F_WAITED_TOO_LONG         0x80100007
-#define SCARD_E_UNKNOWN_READER          0x80100009
-#define SCARD_E_TIMEOUT                 0x8010000A
-#define SCARD_E_SHARING_VIOLATION       0x8010000B
-#define SCARD_E_NO_SMARTCARD            0x8010000C
-#define SCARD_E_UNKNOWN_CARD            0x8010000D
-#define SCARD_E_PROTO_MISMATCH          0x8010000F
-#define SCARD_E_NOT_READY               0x80100010
-#define SCARD_E_SYSTEM_CANCELLED        0x80100012
-#define SCARD_E_NOT_TRANSACTED          0x80100016
-#define SCARD_E_READER_UNAVAILABLE      0x80100017
-
-#define SCARD_W_UNSUPPORTED_CARD        0x80100065
-#define SCARD_W_UNRESPONSIVE_CARD       0x80100066
-#define SCARD_W_UNPOWERED_CARD          0x80100067
-#define SCARD_W_RESET_CARD              0x80100068
-#define SCARD_W_REMOVED_CARD            0x80100069
-
-#define SCARD_E_PCI_TOO_SMALL           0x80100019
-#define SCARD_E_READER_UNSUPPORTED      0x8010001A
-#define SCARD_E_DUPLICATE_READER        0x8010001B
-#define SCARD_E_CARD_UNSUPPORTED        0x8010001C
-#define SCARD_E_NO_SERVICE              0x8010001D
-#define SCARD_E_SERVICE_STOPPED         0x8010001E
-
-#define SCARD_SCOPE_USER                0x0000  /* Scope in user space */
-#define SCARD_SCOPE_TERMINAL            0x0001  /* Scope in terminal */
-#define SCARD_SCOPE_SYSTEM              0x0002  /* Scope in system */
-
-#define SCARD_PROTOCOL_UNSET            0x0000  /* protocol not set */
-#define SCARD_PROTOCOL_T0               0x0001  /* T=0 active protocol. */
-#define SCARD_PROTOCOL_T1               0x0002  /* T=1 active protocol. */
-#define SCARD_PROTOCOL_RAW              0x0004  /* Raw active protocol. */
-#define SCARD_PROTOCOL_T15              0x0008  /* T=15 protocol. */
-
-#define SCARD_PROTOCOL_ANY              (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1)   /* IFD determines prot. */
-
-#define SCARD_SHARE_EXCLUSIVE           0x0001  /* Exclusive mode only */
-#define SCARD_SHARE_SHARED              0x0002  /* Shared mode only */
-#define SCARD_SHARE_DIRECT              0x0003  /* Raw mode only */
-
-#define SCARD_LEAVE_CARD                0x0000  /* Do nothing on close */
-#define SCARD_RESET_CARD                0x0001  /* Reset on close */
-#define SCARD_UNPOWER_CARD              0x0002  /* Power down on close */
-#define SCARD_EJECT_CARD                0x0003  /* Eject on close */
-
-#define SCARD_UNKNOWN                   0x0001  /* Unknown state */
-#define SCARD_ABSENT                    0x0002  /* Card is absent */
-#define SCARD_PRESENT                   0x0004  /* Card is present */
-#define SCARD_SWALLOWED                 0x0008  /* Card not powered */
-#define SCARD_POWERED                   0x0010  /* Card is powered */
-#define SCARD_NEGOTIABLE                0x0020  /* Ready for PTS */
-#define SCARD_SPECIFIC                  0x0040  /* PTS has been set */
-
-#define SCARD_STATE_UNAWARE             0x0000  /* App wants status */
-#define SCARD_STATE_IGNORE              0x0001  /* Ignore this reader */
-#define SCARD_STATE_CHANGED             0x0002  /* State has changed */
-#define SCARD_STATE_UNKNOWN             0x0004  /* Reader unknown */
-#define SCARD_STATE_UNAVAILABLE         0x0008  /* Status unavailable */
-#define SCARD_STATE_EMPTY               0x0010  /* Card removed */
-#define SCARD_STATE_PRESENT             0x0020  /* Card inserted */
-#define SCARD_STATE_ATRMATCH            0x0040  /* ATR matches card */
-#define SCARD_STATE_EXCLUSIVE           0x0080  /* Exclusive Mode */
-#define SCARD_STATE_INUSE               0x0100  /* Shared Mode */
-#define SCARD_STATE_MUTE                0x0200  /* Unresponsive card */
-#define SCARD_STATE_UNPOWERED           0x0400  /* Unpowered card */
-
-/*
- * Tags for requesting card and reader attributes
- */
-
-#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
-
-#define SCARD_CLASS_VENDOR_INFO     1   /* Vendor information definitions */
-#define SCARD_CLASS_COMMUNICATIONS  2   /* Communication definitions */
-#define SCARD_CLASS_PROTOCOL        3   /* Protocol definitions */
-#define SCARD_CLASS_POWER_MGMT      4   /* Power Management definitions */
-#define SCARD_CLASS_SECURITY        5   /* Security Assurance definitions */
-#define SCARD_CLASS_MECHANICAL      6   /* Mechanical characteristic definitions */
-#define SCARD_CLASS_VENDOR_DEFINED  7   /* Vendor specific definitions */
-#define SCARD_CLASS_IFD_PROTOCOL    8   /* Interface Device Protocol options */
-#define SCARD_CLASS_ICC_STATE       9   /* ICC State specific definitions */
-#define SCARD_CLASS_SYSTEM     0x7fff   /* System-specific definitions */
-
-#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100)
-#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101)
-#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102)
-#define SCARD_ATTR_VENDOR_IFD_SERIAL_NO SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103)
-#define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 0x0110)
-#define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0120)
-#define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121)
-#define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122)
-#define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0123)
-#define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0124)
-#define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125)
-#define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0126)
-#define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 0x0131)
-#define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140)
-#define SCARD_ATTR_USER_AUTH_INPUT_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142)
-#define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 0x0150)
-
-#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201)
-#define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0202)
-#define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0203)
-#define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0204)
-#define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0205)
-#define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0206)
-#define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0207)
-#define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0208)
-#define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0209)
-#define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020a)
-#define SCARD_ATTR_CURRENT_EBC_ENCODING SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b)
-#define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020c)
-
-#define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0300)
-#define SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301)
-#define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0302)
-#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303)
-#define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0304)
-
-#define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA000)
-#define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA003)
-#define SCARD_ATTR_ESC_AUTHREQUEST SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005)
-#define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA007)
-
-#define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001)
-#define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002)
-#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
-#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004)
-#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005)
-#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0006)
-#define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0007)
-
-#ifdef UNICODE
-#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W
-#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W
-#else
-#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A
-#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A
+/* restore default structure elements alignment */
+#ifdef __APPLE__
+#pragma pack()
 #endif
 
+#define SCARD_PCI_T0      (&g_rgSCardT0Pci) /**< protocol control information (PCI) for T=0 */
+#define SCARD_PCI_T1      (&g_rgSCardT1Pci) /**< protocol control information (PCI) for T=1 */
+#define SCARD_PCI_RAW      (&g_rgSCardRawPci) /**< protocol control information (PCI) for RAW protocol */
+
+/**
+ * @defgroup ErrorCodes ErrorCodes
+ * @brief Error code documentation
+ *
+ * The error codes descriptions are from
+ * http://msdn.microsoft.com/en-us/library/aa924526.aspx
+ */
+/** @ingroup ErrorCodes */
+#define SCARD_S_SUCCESS                  ((LONG)0x00000000) /**< No error was encountered. */
+/** @ingroup ErrorCodes */
+#define SCARD_F_INTERNAL_ERROR            ((LONG)0x80100001) /**< An internal consistency check failed. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_CANCELLED            ((LONG)0x80100002) /**< The action was cancelled by an SCardCancel request. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_HANDLE            ((LONG)0x80100003) /**< The supplied handle was invalid. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_PARAMETER      ((LONG)0x80100004) /**< One or more of the supplied parameters could not be properly interpreted. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_TARGET            ((LONG)0x80100005) /**< Registry startup information is missing or invalid. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_MEMORY            ((LONG)0x80100006) /**< Not enough memory available to complete this command. */
+/** @ingroup ErrorCodes */
+#define SCARD_F_WAITED_TOO_LONG            ((LONG)0x80100007) /**< An internal consistency timer has expired. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INSUFFICIENT_BUFFER      ((LONG)0x80100008) /**< The data buffer to receive returned data is too small for the returned data. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_UNKNOWN_READER            ((LONG)0x80100009) /**< The specified reader name is not recognized. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_TIMEOUT                  ((LONG)0x8010000A) /**< The user-specified timeout value has expired. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_SHARING_VIOLATION      ((LONG)0x8010000B) /**< The smart card cannot be accessed because of other connections outstanding. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_SMARTCARD            ((LONG)0x8010000C) /**< The operation requires a Smart Card, but no Smart Card is currently in the device. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_UNKNOWN_CARD            ((LONG)0x8010000D) /**< The specified smart card name is not recognized. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_CANT_DISPOSE            ((LONG)0x8010000E) /**< The system could not dispose of the media in the requested manner. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_PROTO_MISMATCH            ((LONG)0x8010000F) /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NOT_READY            ((LONG)0x80100010) /**< The reader or smart card is not ready to accept commands. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_VALUE            ((LONG)0x80100011) /**< One or more of the supplied parameters values could not be properly interpreted. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_SYSTEM_CANCELLED      ((LONG)0x80100012) /**< The action was cancelled by the system, presumably to log off or shut down. */
+/** @ingroup ErrorCodes */
+#define SCARD_F_COMM_ERROR            ((LONG)0x80100013) /**< An internal communications error has been detected. */
+/** @ingroup ErrorCodes */
+#define SCARD_F_UNKNOWN_ERROR            ((LONG)0x80100014) /**< An internal error has been detected, but the source is unknown. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_ATR            ((LONG)0x80100015) /**< An ATR obtained from the registry is not a valid ATR string. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NOT_TRANSACTED            ((LONG)0x80100016) /**< An attempt was made to end a non-existent transaction. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_READER_UNAVAILABLE      ((LONG)0x80100017) /**< The specified reader is not currently available for use. */
+/** @ingroup ErrorCodes */
+#define SCARD_P_SHUTDOWN            ((LONG)0x80100018) /**< The operation has been aborted to allow the server application to exit. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_PCI_TOO_SMALL            ((LONG)0x80100019) /**< The PCI Receive buffer was too small. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_READER_UNSUPPORTED      ((LONG)0x8010001A) /**< The reader driver does not meet minimal requirements for support. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_DUPLICATE_READER      ((LONG)0x8010001B) /**< The reader driver did not produce a unique reader name. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_CARD_UNSUPPORTED      ((LONG)0x8010001C) /**< The smart card does not meet minimal requirements for support. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_SERVICE            ((LONG)0x8010001D) /**< The Smart card resource manager is not running. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_SERVICE_STOPPED            ((LONG)0x8010001E) /**< The Smart card resource manager has shut down. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_UNEXPECTED            ((LONG)0x8010001F) /**< An unexpected card error has occurred. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_UNSUPPORTED_FEATURE      ((LONG)0x8010001F) /**< This smart card does not support the requested feature. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_ICC_INSTALLATION      ((LONG)0x80100020) /**< No primary provider can be found for the smart card. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_ICC_CREATEORDER            ((LONG)0x80100021) /**< The requested order of object creation is not supported. */
+/** @ingroup ErrorCodes */
+/* #define SCARD_E_UNSUPPORTED_FEATURE      ((LONG)0x80100022) / **< This smart card does not support the requested feature. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_DIR_NOT_FOUND            ((LONG)0x80100023) /**< The identified directory does not exist in the smart card. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_FILE_NOT_FOUND            ((LONG)0x80100024) /**< The identified file does not exist in the smart card. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_DIR                  ((LONG)0x80100025) /**< The supplied path does not represent a smart card directory. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_FILE                  ((LONG)0x80100026) /**< The supplied path does not represent a smart card file. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_ACCESS            ((LONG)0x80100027) /**< Access is denied to this file. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_WRITE_TOO_MANY            ((LONG)0x80100028) /**< The smart card does not have enough memory to store the information. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_BAD_SEEK            ((LONG)0x80100029) /**< There was an error trying to set the smart card file object pointer. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_INVALID_CHV            ((LONG)0x8010002A) /**< The supplied PIN is incorrect. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_UNKNOWN_RES_MNG            ((LONG)0x8010002B) /**< An unrecognized error code was returned from a layered component. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_SUCH_CERTIFICATE      ((LONG)0x8010002C) /**< The requested certificate does not exist. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_CERTIFICATE_UNAVAILABLE      ((LONG)0x8010002D) /**< The requested certificate could not be obtained. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_READERS_AVAILABLE    ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_COMM_DATA_LOST            ((LONG)0x8010002F) /**< A communications error with the smart card has been detected. Retry the operation. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_NO_KEY_CONTAINER      ((LONG)0x80100030) /**< The requested key container does not exist on the smart card. */
+/** @ingroup ErrorCodes */
+#define SCARD_E_SERVER_TOO_BUSY            ((LONG)0x80100031) /**< The Smart Card Resource Manager is too busy to complete this operation. */
+
+/** @ingroup ErrorCodes */
+#define SCARD_W_UNSUPPORTED_CARD      ((LONG)0x80100065) /**< The reader cannot communicate with the card, due to ATR string configuration conflicts. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_UNRESPONSIVE_CARD      ((LONG)0x80100066) /**< The smart card is not responding to a reset. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_UNPOWERED_CARD            ((LONG)0x80100067) /**< Power has been removed from the smart card, so that further communication is not possible. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_RESET_CARD            ((LONG)0x80100068) /**< The smart card has been reset, so any shared state information is invalid. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_REMOVED_CARD            ((LONG)0x80100069) /**< The smart card has been removed, so further communication is not possible. */
+
+/** @ingroup ErrorCodes */
+#define SCARD_W_SECURITY_VIOLATION      ((LONG)0x8010006A) /**< Access was denied because of a security violation. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_WRONG_CHV            ((LONG)0x8010006B) /**< The card cannot be accessed because the wrong PIN was presented. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_CHV_BLOCKED            ((LONG)0x8010006C) /**< The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_EOF                  ((LONG)0x8010006D) /**< The end of the smart card file has been reached. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_CANCELLED_BY_USER      ((LONG)0x8010006E) /**< The user pressed "Cancel" on a Smart Card Selection Dialog. */
+/** @ingroup ErrorCodes */
+#define SCARD_W_CARD_NOT_AUTHENTICATED      ((LONG)0x8010006F) /**< No PIN was presented to the smart card. */
+
+#define SCARD_AUTOALLOCATE (DWORD)(-1)      /**< see SCardFreeMemory() */
+#define SCARD_SCOPE_USER            0x0000      /**< Scope in user space */
+#define SCARD_SCOPE_TERMINAL            0x0001      /**< Scope in terminal */
+#define SCARD_SCOPE_SYSTEM            0x0002      /**< Scope in system */
+#define SCARD_SCOPE_GLOBAL            0x0003      /**< Scope is global */
+
+#define SCARD_PROTOCOL_UNDEFINED      0x0000      /**< protocol not set */
+#define SCARD_PROTOCOL_UNSET SCARD_PROTOCOL_UNDEFINED      /* backward compat */
+#define SCARD_PROTOCOL_T0            0x0001      /**< T=0 active protocol. */
+#define SCARD_PROTOCOL_T1            0x0002      /**< T=1 active protocol. */
+#define SCARD_PROTOCOL_RAW            0x0004      /**< Raw active protocol. */
+#define SCARD_PROTOCOL_T15            0x0008      /**< T=15 protocol. */
+
+#define SCARD_PROTOCOL_ANY            (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1)      /**< IFD determines prot. */
+
+#define SCARD_SHARE_EXCLUSIVE            0x0001      /**< Exclusive mode only */
+#define SCARD_SHARE_SHARED            0x0002      /**< Shared mode only */
+#define SCARD_SHARE_DIRECT            0x0003      /**< Raw mode only */
+
+#define SCARD_LEAVE_CARD            0x0000      /**< Do nothing on close */
+#define SCARD_RESET_CARD            0x0001      /**< Reset on close */
+#define SCARD_UNPOWER_CARD            0x0002      /**< Power down on close */
+#define SCARD_EJECT_CARD            0x0003      /**< Eject on close */
+
+#define SCARD_UNKNOWN                  0x0001      /**< Unknown state */
+#define SCARD_ABSENT                  0x0002      /**< Card is absent */
+#define SCARD_PRESENT                  0x0004      /**< Card is present */
+#define SCARD_SWALLOWED                  0x0008      /**< Card not powered */
+#define SCARD_POWERED                  0x0010      /**< Card is powered */
+#define SCARD_NEGOTIABLE            0x0020      /**< Ready for PTS */
+#define SCARD_SPECIFIC                  0x0040      /**< PTS has been set */
+
+#define SCARD_STATE_UNAWARE            0x0000      /**< App wants status */
+#define SCARD_STATE_IGNORE            0x0001      /**< Ignore this reader */
+#define SCARD_STATE_CHANGED            0x0002      /**< State has changed */
+#define SCARD_STATE_UNKNOWN            0x0004      /**< Reader unknown */
+#define SCARD_STATE_UNAVAILABLE            0x0008      /**< Status unavailable */
+#define SCARD_STATE_EMPTY            0x0010      /**< Card removed */
+#define SCARD_STATE_PRESENT            0x0020      /**< Card inserted */
+#define SCARD_STATE_ATRMATCH            0x0040      /**< ATR matches card */
+#define SCARD_STATE_EXCLUSIVE            0x0080      /**< Exclusive Mode */
+#define SCARD_STATE_INUSE            0x0100      /**< Shared Mode */
+#define SCARD_STATE_MUTE            0x0200      /**< Unresponsive card */
+#define SCARD_STATE_UNPOWERED            0x0400      /**< Unpowered card */
+
+#ifndef INFINITE
+#define INFINITE                  0xFFFFFFFF      /**< Infinite timeout */
 #endif
 
-/* PC/SC Lite specific extensions */
-#define SCARD_W_INSERTED_CARD           0x8010006A
-#define SCARD_E_UNSUPPORTED_FEATURE     0x8010001F
+#define PCSCLITE_VERSION_NUMBER            "1.8.24"      /**< Current version */
+/** Maximum readers context (a slot is count as a reader) */
+#define PCSCLITE_MAX_READERS_CONTEXTS                  16
 
-#define SCARD_SCOPE_GLOBAL              0x0003  /* Scope is global */
-
-#define SCARD_RESET                     0x0001  /* Card was reset */
-#define SCARD_INSERTED                  0x0002  /* Card was inserted */
-#define SCARD_REMOVED                   0x0004  /* Card was removed */
-
-#define BLOCK_STATUS_RESUME             0x00FF  /* Normal resume */
-#define BLOCK_STATUS_BLOCKING           0x00FA  /* Function is blocking */
-
-#define PCSCLITE_CONFIG_DIR             "/etc"
-
-#ifndef USE_IPCDIR
-#define PCSCLITE_IPC_DIR                "/var/run"
-#else
-#define PCSCLITE_IPC_DIR                USE_IPCDIR
-#endif
-
-#define PCSCLITE_READER_CONFIG          PCSCLITE_CONFIG_DIR "/reader.conf"
-#define PCSCLITE_PUBSHM_FILE            PCSCLITE_IPC_DIR "/pcscd.pub"
-#define PCSCLITE_CSOCK_NAME             PCSCLITE_IPC_DIR "/pcscd.comm"
-
-#define PCSCLITE_SVC_IDENTITY           0x01030000      /* Service ID */
-
-#ifndef INFINITE
-#define INFINITE                        0xFFFFFFFF      /* Infinite timeout */
-#endif
-#define PCSCLITE_INFINITE_TIMEOUT       4320000         /* 50 day infinite t/o */
-
-#define PCSCLITE_VERSION_NUMBER         "1.2.9-beta7"   /* Current version */
-#define PCSCLITE_CLIENT_ATTEMPTS        120             /* Attempts to reach sv */
-#define PCSCLITE_MCLIENT_ATTEMPTS       20              /* Attempts to reach sv */
-#define PCSCLITE_STATUS_POLL_RATE       400000          /* Status polling rate */
-#define PCSCLITE_MSG_KEY_LEN            16              /* App ID key length */
-#define PCSCLITE_RW_ATTEMPTS            100             /* Attempts to rd/wrt */
-
-/* Maximum applications */
-#define PCSCLITE_MAX_APPLICATIONS                       16
-/* Maximum contexts by application */
-#define PCSCLITE_MAX_APPLICATION_CONTEXTS               16
-/* Maximum of applications contexts that pcscd can accept */
-#define PCSCLITE_MAX_APPLICATIONS_CONTEXTS \
-        PCSCLITE_MAX_APPLICATIONS * PCSCLITE_MAX_APPLICATION_CONTEXTS