changeset 58008:5b540d7a1420

Merge
author psadhukhan
date Tue, 11 Feb 2020 13:41:48 +0530
parents 0596ee6950a6 6925fca95959
children eaefceb7f52e
files test/jdk/ProblemList.txt test/jdk/java/net/httpclient/ssltest/bad.keystore test/jdk/java/net/httpclient/ssltest/good.keystore test/jdk/java/net/httpclient/ssltest/loopback.keystore
diffstat 115 files changed, 3472 insertions(+), 1111 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sat Feb 08 18:48:42 2020 -0800
+++ b/.hgtags	Tue Feb 11 13:41:48 2020 +0530
@@ -618,3 +618,4 @@
 c7d4f2849dbfb755fc5860b362a4044ea0c9e082 jdk-15+8
 4a87bb7ebfd7f6a25ec59a5982fe3607242777f8 jdk-14+35
 62b5bfef8d618e08e6f3a56cf1fb0e67e89e9cc2 jdk-15+9
+bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14+36
--- a/make/GenerateLinkOptData.gmk	Sat Feb 08 18:48:42 2020 -0800
+++ b/make/GenerateLinkOptData.gmk	Tue Feb 11 13:41:48 2020 +0530
@@ -75,6 +75,7 @@
 	$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@.raw \
 	    -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
 	    -Duser.language=en -Duser.country=US \
+	    --module-path $(SUPPORT_OUTPUTDIR)/classlist.jar \
 	    -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
 	    build.tools.classlist.HelloClasslist \
 	    2> $(LINK_OPT_DIR)/stderr > $(JLI_TRACE_FILE) \
--- a/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Tue Feb 11 13:41:48 2020 +0530
@@ -31,6 +31,9 @@
  */
 package build.tools.classlist;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.net.InetAddress;
 import java.nio.file.FileSystems;
 import java.time.LocalDateTime;
@@ -55,19 +58,20 @@
 
     private static final Logger LOGGER = Logger.getLogger("Hello");
 
-    public static void main(String ... args) {
+    public static void main(String ... args) throws Throwable {
 
         FileSystems.getDefault();
 
         List<String> strings = Arrays.asList("Hello", "World!", "From: ",
-              InetAddress.getLoopbackAddress().toString());
+                InetAddress.getLoopbackAddress().toString());
 
         String helloWorld = strings.parallelStream()
-              .map(s -> s.toLowerCase(Locale.ROOT))
-              .collect(joining(","));
+                .map(s -> s.toLowerCase(Locale.ROOT))
+                .collect(joining(","));
 
-        Stream.of(helloWorld.split(","))
-              .forEach(System.out::println);
+        Stream.of(helloWorld.split("([,x-z]{1,3})([\\s]*)"))
+                .map(String::toString)
+                .forEach(System.out::println);
 
         // Common concatenation patterns
         String SS     = String.valueOf(args.length) + String.valueOf(args.length);
@@ -83,6 +87,10 @@
         String SCSCS  = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length);
         String CI     = "string" + args.length;
         String IC     = args.length + "string";
+        String SI     = String.valueOf(args.length) + args.length;
+        String IS     = args.length + String.valueOf(args.length);
+        String CIS    = "string" + args.length + String.valueOf(args.length);
+        String CSCI   = "string" + String.valueOf(args.length) + "string" + args.length;
         String CIC    = "string" + args.length + "string";
         String CICI   = "string" + args.length + "string" + args.length;
         String CJ     = "string" + System.currentTimeMillis();
@@ -99,7 +107,31 @@
                 DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.ROOT)
                         .format(new Date()));
 
+        // A selection of trivial and relatively common MH operations
+        invoke(MethodHandles.identity(double.class), 1.0);
+        invoke(MethodHandles.identity(int.class), 1);
+        invoke(MethodHandles.identity(String.class), "x");
+
+        invoke(handle("staticMethod_V", MethodType.methodType(void.class)));
+
         LOGGER.log(Level.FINE, "New Date: " + newDate + " - old: " + oldDate);
     }
 
+    public static void staticMethod_V() {}
+
+    private static MethodHandle handle(String name, MethodType type) throws Throwable {
+        return MethodHandles.lookup().findStatic(HelloClasslist.class, name, type);
+    }
+
+    private static Object invoke(MethodHandle mh, Object ... args) throws Throwable {
+        try {
+            for (Object o : args) {
+                mh = MethodHandles.insertArguments(mh, 0, o);
+            }
+            return mh.invoke();
+        } catch (Throwable t) {
+            LOGGER.warning("Failed to find, link and/or invoke " + mh.toString() + ": " + t.getMessage());
+            throw t;
+        }
+    }
 }
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -672,11 +672,14 @@
     }
   }
   if (FLAG_IS_DEFAULT(UseAVX)) {
-    FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
-    if (is_intel_family_core() && _model == CPU_MODEL_SKYLAKE && _stepping < 5) {
-      FLAG_SET_DEFAULT(UseAVX, 2);  //Set UseAVX=2 for Skylake
+    // Don't use AVX-512 on older Skylakes unless explicitly requested.
+    if (use_avx_limit > 2 && is_intel_skylake() && _stepping < 5) {
+      FLAG_SET_DEFAULT(UseAVX, 2);
+    } else {
+      FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
     }
-  } else if (UseAVX > use_avx_limit) {
+  }
+  if (UseAVX > use_avx_limit) {
     warning("UseAVX=%d is not supported on this CPU, setting it to UseAVX=%d", (int) UseAVX, use_avx_limit);
     FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
   } else if (UseAVX < 0) {
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -868,6 +868,9 @@
   static bool is_intel_family_core() { return is_intel() &&
                                        extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
 
+  static bool is_intel_skylake() { return is_intel_family_core() &&
+                                          extended_cpu_model() == CPU_MODEL_SKYLAKE; }
+
   static bool is_intel_tsc_synched_at_init()  {
     if (is_intel_family_core()) {
       uint32_t ext_model = extended_cpu_model();
--- a/src/hotspot/os/bsd/osThread_bsd.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/os/bsd/osThread_bsd.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,12 @@
 #else
   _thread_id        = NULL;
 #endif
+  _unique_thread_id = 0;
   _pthread_id       = NULL;
-  _siginfo = NULL;
-  _ucontext = NULL;
-  _expanding_stack = 0;
-  _alt_sig_stack = NULL;
+  _siginfo          = NULL;
+  _ucontext         = NULL;
+  _expanding_stack  = 0;
+  _alt_sig_stack    = NULL;
 
   sigemptyset(&_caller_sigmask);
 
@@ -49,6 +50,22 @@
   assert(_startThread_lock !=NULL, "check");
 }
 
+// Additional thread_id used to correlate threads in SA
+void OSThread::set_unique_thread_id() {
+#ifdef __APPLE__
+  thread_identifier_info_data_t m_ident_info;
+  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+
+  mach_port_t mach_thread_port = mach_thread_self();
+  guarantee(mach_thread_port != 0, "just checking");
+  thread_info(mach_thread_port, THREAD_IDENTIFIER_INFO,
+              (thread_info_t) &m_ident_info, &count);
+  mach_port_deallocate(mach_task_self(), mach_thread_port);
+
+  _unique_thread_id = m_ident_info.thread_id;
+#endif
+}
+
 void OSThread::pd_destroy() {
   delete _startThread_lock;
 }
--- a/src/hotspot/os/bsd/osThread_bsd.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/os/bsd/osThread_bsd.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,9 +82,7 @@
     _pthread_id = tid;
   }
 
-  void set_unique_thread_id(uint64_t id) {
-    _unique_thread_id = id;
-  }
+  void set_unique_thread_id();
 
   // ***************************************************************
   // suspension support.
--- a/src/hotspot/os/bsd/os_bsd.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -634,19 +634,6 @@
 objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL;
 #endif
 
-#ifdef __APPLE__
-static uint64_t locate_unique_thread_id(mach_port_t mach_thread_port) {
-  // Additional thread_id used to correlate threads in SA
-  thread_identifier_info_data_t     m_ident_info;
-  mach_msg_type_number_t            count = THREAD_IDENTIFIER_INFO_COUNT;
-
-  thread_info(mach_thread_port, THREAD_IDENTIFIER_INFO,
-              (thread_info_t) &m_ident_info, &count);
-
-  return m_ident_info.thread_id;
-}
-#endif
-
 // Thread start routine for all newly created threads
 static void *thread_native_entry(Thread *thread) {
 
@@ -672,10 +659,10 @@
     os::current_thread_id(), (uintx) pthread_self());
 
 #ifdef __APPLE__
-  uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
-  guarantee(unique_thread_id != 0, "unique thread id was not found");
-  osthread->set_unique_thread_id(unique_thread_id);
+  // Store unique OS X thread id used by SA
+  osthread->set_unique_thread_id();
 #endif
+
   // initialize signal mask for this thread
   os::Bsd::hotspot_sigmask(thread);
 
@@ -823,12 +810,12 @@
 
   osthread->set_thread_id(os::Bsd::gettid());
 
+#ifdef __APPLE__
+  // Store unique OS X thread id used by SA
+  osthread->set_unique_thread_id();
+#endif
+
   // Store pthread info into the OSThread
-#ifdef __APPLE__
-  uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
-  guarantee(unique_thread_id != 0, "just checking");
-  osthread->set_unique_thread_id(unique_thread_id);
-#endif
   osthread->set_pthread_id(::pthread_self());
 
   // initialize floating point control register
@@ -1100,12 +1087,11 @@
 pid_t os::Bsd::gettid() {
   int retval = -1;
 
-#ifdef __APPLE__ //XNU kernel
-  // despite the fact mach port is actually not a thread id use it
-  // instead of syscall(SYS_thread_selfid) as it certainly fits to u4
-  retval = ::pthread_mach_thread_np(::pthread_self());
-  guarantee(retval != 0, "just checking");
-  return retval;
+#ifdef __APPLE__ // XNU kernel
+  mach_port_t port = mach_thread_self();
+  guarantee(MACH_PORT_VALID(port), "just checking");
+  mach_port_deallocate(mach_task_self(), port);
+  return (pid_t)port;
 
 #else
   #ifdef __FreeBSD__
@@ -1128,7 +1114,7 @@
 
 intx os::current_thread_id() {
 #ifdef __APPLE__
-  return (intx)::pthread_mach_thread_np(::pthread_self());
+  return (intx)os::Bsd::gettid();
 #else
   return (intx)::pthread_self();
 #endif
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -213,14 +213,19 @@
   }
 
   ciInstanceKlass* self = this;
-  for (;;) {
-    assert(self->is_loaded(), "must be loaded to have size");
-    ciInstanceKlass* super = self->super();
-    if (super == NULL || super->nof_nonstatic_fields() == 0 ||
-        !super->contains_field_offset(offset)) {
-      return self;
-    } else {
-      self = super;  // return super->get_canonical_holder(offset)
+  assert(self->is_loaded(), "must be loaded to access field info");
+  ciField* field = self->get_field_by_offset(offset, false);
+  if (field != NULL) {
+    return field->holder();
+  } else {
+    for (;;) {
+      assert(self->is_loaded(), "must be loaded to have size");
+      ciInstanceKlass* super = self->super();
+      if (super == NULL || super->nof_nonstatic_fields() == 0) {
+        return self;
+      } else {
+        self = super;  // return super->get_canonical_holder(offset)
+      }
     }
   }
 }
@@ -392,6 +397,13 @@
 }
 
 // ------------------------------------------------------------------
+// ciInstanceKlass::contains_field_offset
+bool ciInstanceKlass::contains_field_offset(int offset) {
+  VM_ENTRY_MARK;
+  return get_instanceKlass()->contains_field_offset(offset);
+}
+
+// ------------------------------------------------------------------
 // ciInstanceKlass::get_field_by_offset
 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
   if (!is_static) {
@@ -457,15 +469,9 @@
   ciInstanceKlass* super = this->super();
   GrowableArray<ciField*>* super_fields = NULL;
   if (super != NULL && super->has_nonstatic_fields()) {
-    int super_fsize  = super->nonstatic_field_size() * heapOopSize;
     int super_flen   = super->nof_nonstatic_fields();
     super_fields = super->_nonstatic_fields;
     assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
-    // See if I am no larger than my super; if so, I can use his fields.
-    if (fsize == super_fsize) {
-      _nonstatic_fields = super_fields;
-      return super_fields->length();
-    }
   }
 
   GrowableArray<ciField*>* fields = NULL;
--- a/src/hotspot/share/ci/ciInstanceKlass.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/ci/ciInstanceKlass.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -225,9 +225,7 @@
   ciInstanceKlass* unique_concrete_subklass();
   bool has_finalizable_subclass();
 
-  bool contains_field_offset(int offset) {
-    return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size());
-  }
+  bool contains_field_offset(int offset);
 
   // Get the instance of java.lang.Class corresponding to
   // this klass.  This instance is used for locking of
--- a/src/hotspot/share/classfile/classFileParser.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -30,6 +30,7 @@
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/defaultMethods.hpp"
 #include "classfile/dictionary.hpp"
+#include "classfile/fieldLayoutBuilder.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
@@ -60,6 +61,7 @@
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
@@ -1686,8 +1688,12 @@
     field->set_allocation_type(atype);
 
     // After field is initialized with type, we can augment it with aux info
-    if (parsed_annotations.has_any_annotations())
+    if (parsed_annotations.has_any_annotations()) {
       parsed_annotations.apply_to(field);
+      if (field->is_contended()) {
+        _has_contended_fields = true;
+      }
+    }
   }
 
   int index = length;
@@ -3932,39 +3938,6 @@
   return super_klass;
 }
 
-static unsigned int compute_oop_map_count(const InstanceKlass* super,
-                                          unsigned int nonstatic_oop_map_count,
-                                          int first_nonstatic_oop_offset) {
-
-  unsigned int map_count =
-    NULL == super ? 0 : super->nonstatic_oop_map_count();
-  if (nonstatic_oop_map_count > 0) {
-    // We have oops to add to map
-    if (map_count == 0) {
-      map_count = nonstatic_oop_map_count;
-    }
-    else {
-      // Check whether we should add a new map block or whether the last one can
-      // be extended
-      const OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps();
-      const OopMapBlock* const last_map = first_map + map_count - 1;
-
-      const int next_offset = last_map->offset() + last_map->count() * heapOopSize;
-      if (next_offset == first_nonstatic_oop_offset) {
-        // There is no gap bettwen superklass's last oop field and first
-        // local oop field, merge maps.
-        nonstatic_oop_map_count -= 1;
-      }
-      else {
-        // Superklass didn't end with a oop field, add extra maps
-        assert(next_offset < first_nonstatic_oop_offset, "just checking");
-      }
-      map_count += nonstatic_oop_map_count;
-    }
-  }
-  return map_count;
-}
-
 #ifndef PRODUCT
 static void print_field_layout(const Symbol* name,
                                Array<u2>* fields,
@@ -4002,18 +3975,121 @@
 }
 #endif
 
-// Values needed for oopmap and InstanceKlass creation
-class ClassFileParser::FieldLayoutInfo : public ResourceObj {
- public:
-  int*          nonstatic_oop_offsets;
-  unsigned int* nonstatic_oop_counts;
-  unsigned int  nonstatic_oop_map_count;
-  unsigned int  total_oop_map_count;
-  int           instance_size;
-  int           nonstatic_field_size;
-  int           static_field_size;
-  bool          has_nonstatic_fields;
-};
+OopMapBlocksBuilder::OopMapBlocksBuilder(unsigned int max_blocks) {
+  _max_nonstatic_oop_maps = max_blocks;
+  _nonstatic_oop_map_count = 0;
+  if (max_blocks == 0) {
+    _nonstatic_oop_maps = NULL;
+  } else {
+    _nonstatic_oop_maps =
+        NEW_RESOURCE_ARRAY(OopMapBlock, _max_nonstatic_oop_maps);
+    memset(_nonstatic_oop_maps, 0, sizeof(OopMapBlock) * max_blocks);
+  }
+}
+
+OopMapBlock* OopMapBlocksBuilder::last_oop_map() const {
+  assert(_nonstatic_oop_map_count > 0, "Has no oop maps");
+  return _nonstatic_oop_maps + (_nonstatic_oop_map_count - 1);
+}
+
+// addition of super oop maps
+void OopMapBlocksBuilder::initialize_inherited_blocks(OopMapBlock* blocks, unsigned int nof_blocks) {
+  assert(nof_blocks && _nonstatic_oop_map_count == 0 &&
+         nof_blocks <= _max_nonstatic_oop_maps, "invariant");
+
+  memcpy(_nonstatic_oop_maps, blocks, sizeof(OopMapBlock) * nof_blocks);
+  _nonstatic_oop_map_count += nof_blocks;
+}
+
+// collection of oops
+void OopMapBlocksBuilder::add(int offset, int count) {
+  if (_nonstatic_oop_map_count == 0) {
+    _nonstatic_oop_map_count++;
+  }
+  OopMapBlock* nonstatic_oop_map = last_oop_map();
+  if (nonstatic_oop_map->count() == 0) {  // Unused map, set it up
+    nonstatic_oop_map->set_offset(offset);
+    nonstatic_oop_map->set_count(count);
+  } else if (nonstatic_oop_map->is_contiguous(offset)) { // contiguous, add
+    nonstatic_oop_map->increment_count(count);
+  } else { // Need a new one...
+    _nonstatic_oop_map_count++;
+    assert(_nonstatic_oop_map_count <= _max_nonstatic_oop_maps, "range check");
+    nonstatic_oop_map = last_oop_map();
+    nonstatic_oop_map->set_offset(offset);
+    nonstatic_oop_map->set_count(count);
+  }
+}
+
+// general purpose copy, e.g. into allocated instanceKlass
+void OopMapBlocksBuilder::copy(OopMapBlock* dst) {
+  if (_nonstatic_oop_map_count != 0) {
+    memcpy(dst, _nonstatic_oop_maps, sizeof(OopMapBlock) * _nonstatic_oop_map_count);
+  }
+}
+
+// Sort and compact adjacent blocks
+void OopMapBlocksBuilder::compact() {
+  if (_nonstatic_oop_map_count <= 1) {
+    return;
+  }
+  /*
+   * Since field layout sneeks in oops before values, we will be able to condense
+   * blocks. There is potential to compact between super, own refs and values
+   * containing refs.
+   *
+   * Currently compaction is slightly limited due to values being 8 byte aligned.
+   * This may well change: FixMe if it doesn't, the code below is fairly general purpose
+   * and maybe it doesn't need to be.
+   */
+  qsort(_nonstatic_oop_maps, _nonstatic_oop_map_count, sizeof(OopMapBlock),
+        (_sort_Fn)OopMapBlock::compare_offset);
+  if (_nonstatic_oop_map_count < 2) {
+    return;
+  }
+
+  // Make a temp copy, and iterate through and copy back into the original
+  ResourceMark rm;
+  OopMapBlock* oop_maps_copy =
+      NEW_RESOURCE_ARRAY(OopMapBlock, _nonstatic_oop_map_count);
+  OopMapBlock* oop_maps_copy_end = oop_maps_copy + _nonstatic_oop_map_count;
+  copy(oop_maps_copy);
+  OopMapBlock* nonstatic_oop_map = _nonstatic_oop_maps;
+  unsigned int new_count = 1;
+  oop_maps_copy++;
+  while(oop_maps_copy < oop_maps_copy_end) {
+    assert(nonstatic_oop_map->offset() < oop_maps_copy->offset(), "invariant");
+    if (nonstatic_oop_map->is_contiguous(oop_maps_copy->offset())) {
+      nonstatic_oop_map->increment_count(oop_maps_copy->count());
+    } else {
+      nonstatic_oop_map++;
+      new_count++;
+      nonstatic_oop_map->set_offset(oop_maps_copy->offset());
+      nonstatic_oop_map->set_count(oop_maps_copy->count());
+    }
+    oop_maps_copy++;
+  }
+  assert(new_count <= _nonstatic_oop_map_count, "end up with more maps after compact() ?");
+  _nonstatic_oop_map_count = new_count;
+}
+
+void OopMapBlocksBuilder::print_on(outputStream* st) const {
+  st->print_cr("  OopMapBlocks: %3d  /%3d", _nonstatic_oop_map_count, _max_nonstatic_oop_maps);
+  if (_nonstatic_oop_map_count > 0) {
+    OopMapBlock* map = _nonstatic_oop_maps;
+    OopMapBlock* last_map = last_oop_map();
+    assert(map <= last_map, "Last less than first");
+    while (map <= last_map) {
+      st->print_cr("    Offset: %3d  -%3d Count: %3d", map->offset(),
+                   map->offset() + map->offset_span() - heapOopSize, map->count());
+      map++;
+    }
+  }
+}
+
+void OopMapBlocksBuilder::print_value_on(outputStream* st) const {
+  print_on(st);
+}
 
 // Layout fields and fill in FieldLayoutInfo.  Could use more refactoring!
 void ClassFileParser::layout_fields(ConstantPool* cp,
@@ -4100,16 +4176,15 @@
   // count[i] oops following. Before we know how many regions are required,
   // we pessimistically allocate the maps to fit all the oops into the
   // distinct regions.
-  //
-  // TODO: We add +1 to always allocate non-zero resource arrays; we need
-  // to figure out if we still need to do this.
-  unsigned int nonstatic_oop_map_count = 0;
-  unsigned int max_nonstatic_oop_maps  = fac->count[NONSTATIC_OOP] + 1;
-
-  int* nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
-            THREAD, int, max_nonstatic_oop_maps);
-  unsigned int* const nonstatic_oop_counts  = NEW_RESOURCE_ARRAY_IN_THREAD(
-            THREAD, unsigned int, max_nonstatic_oop_maps);
+
+  int super_oop_map_count = (_super_klass == NULL) ? 0 :_super_klass->nonstatic_oop_map_count();
+  int max_oop_map_count = super_oop_map_count + fac->count[NONSTATIC_OOP];
+
+  OopMapBlocksBuilder* nonstatic_oop_maps = new OopMapBlocksBuilder(max_oop_map_count);
+  if (super_oop_map_count > 0) {
+    nonstatic_oop_maps->initialize_inherited_blocks(_super_klass->start_of_nonstatic_oop_maps(),
+                                                    _super_klass->nonstatic_oop_map_count());
+  }
 
   int first_nonstatic_oop_offset = 0; // will be set for first oop field
 
@@ -4260,26 +4335,7 @@
           real_offset = next_nonstatic_oop_offset;
           next_nonstatic_oop_offset += heapOopSize;
         }
-
-        // Record this oop in the oop maps
-        if( nonstatic_oop_map_count > 0 &&
-            nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
-            real_offset -
-            int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
-            heapOopSize ) {
-          // This oop is adjacent to the previous one, add to current oop map
-          assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
-          nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
-        } else {
-          // This oop is not adjacent to the previous one, create new oop map
-          assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
-          nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
-          nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
-          nonstatic_oop_map_count += 1;
-          if( first_nonstatic_oop_offset == 0 ) { // Undefined
-            first_nonstatic_oop_offset = real_offset;
-          }
-        }
+        nonstatic_oop_maps->add(real_offset, 1);
         break;
       case NONSTATIC_BYTE:
         if( nonstatic_byte_space_count > 0 ) {
@@ -4392,26 +4448,7 @@
             next_nonstatic_padded_offset = align_up(next_nonstatic_padded_offset, heapOopSize);
             real_offset = next_nonstatic_padded_offset;
             next_nonstatic_padded_offset += heapOopSize;
-
-            // Record this oop in the oop maps
-            if( nonstatic_oop_map_count > 0 &&
-                nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
-                real_offset -
-                int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
-                heapOopSize ) {
-              // This oop is adjacent to the previous one, add to current oop map
-              assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
-              nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
-            } else {
-              // This oop is not adjacent to the previous one, create new oop map
-              assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
-              nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
-              nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
-              nonstatic_oop_map_count += 1;
-              if( first_nonstatic_oop_offset == 0 ) { // Undefined
-                first_nonstatic_oop_offset = real_offset;
-              }
-            }
+            nonstatic_oop_maps->add(real_offset, 1);
             break;
 
           default:
@@ -4475,9 +4512,7 @@
          (nonstatic_fields_count > 0), "double-check nonstatic start/end");
 
   // Number of non-static oop map blocks allocated at end of klass.
-  const unsigned int total_oop_map_count =
-    compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
-                          first_nonstatic_oop_offset);
+  nonstatic_oop_maps->compact();
 
 #ifndef PRODUCT
   if (PrintFieldLayout) {
@@ -4492,58 +4527,13 @@
 
 #endif
   // Pass back information needed for InstanceKlass creation
-  info->nonstatic_oop_offsets = nonstatic_oop_offsets;
-  info->nonstatic_oop_counts = nonstatic_oop_counts;
-  info->nonstatic_oop_map_count = nonstatic_oop_map_count;
-  info->total_oop_map_count = total_oop_map_count;
-  info->instance_size = instance_size;
-  info->static_field_size = static_field_size;
-  info->nonstatic_field_size = nonstatic_field_size;
-  info->has_nonstatic_fields = has_nonstatic_fields;
+  info->oop_map_blocks = nonstatic_oop_maps;
+  info->_instance_size = instance_size;
+  info->_static_field_size = static_field_size;
+  info->_nonstatic_field_size = nonstatic_field_size;
+  info->_has_nonstatic_fields = has_nonstatic_fields;
 }
 
-static void fill_oop_maps(const InstanceKlass* k,
-                          unsigned int nonstatic_oop_map_count,
-                          const int* nonstatic_oop_offsets,
-                          const unsigned int* nonstatic_oop_counts) {
-
-  assert(k != NULL, "invariant");
-
-  OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps();
-  const InstanceKlass* const super = k->superklass();
-  const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0;
-  if (super_count > 0) {
-    // Copy maps from superklass
-    OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps();
-    for (unsigned int i = 0; i < super_count; ++i) {
-      *this_oop_map++ = *super_oop_map++;
-    }
-  }
-
-  if (nonstatic_oop_map_count > 0) {
-    if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) {
-      // The counts differ because there is no gap between superklass's last oop
-      // field and the first local oop field.  Extend the last oop map copied
-      // from the superklass instead of creating new one.
-      nonstatic_oop_map_count--;
-      nonstatic_oop_offsets++;
-      this_oop_map--;
-      this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++);
-      this_oop_map++;
-    }
-
-    // Add new map blocks, fill them
-    while (nonstatic_oop_map_count-- > 0) {
-      this_oop_map->set_offset(*nonstatic_oop_offsets++);
-      this_oop_map->set_count(*nonstatic_oop_counts++);
-      this_oop_map++;
-    }
-    assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() ==
-           this_oop_map, "sanity");
-  }
-}
-
-
 void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
   assert(ik != NULL, "invariant");
 
@@ -5498,17 +5488,17 @@
 
 int ClassFileParser::static_field_size() const {
   assert(_field_info != NULL, "invariant");
-  return _field_info->static_field_size;
+  return _field_info->_static_field_size;
 }
 
 int ClassFileParser::total_oop_map_count() const {
   assert(_field_info != NULL, "invariant");
-  return _field_info->total_oop_map_count;
+  return _field_info->oop_map_blocks->_nonstatic_oop_map_count;
 }
 
 jint ClassFileParser::layout_size() const {
   assert(_field_info != NULL, "invariant");
-  return _field_info->instance_size;
+  return _field_info->_instance_size;
 }
 
 static void check_methods_for_intrinsics(const InstanceKlass* ik,
@@ -5652,19 +5642,19 @@
   set_klass_to_deallocate(ik);
 
   assert(_field_info != NULL, "invariant");
-  assert(ik->static_field_size() == _field_info->static_field_size, "sanity");
-  assert(ik->nonstatic_oop_map_count() == _field_info->total_oop_map_count,
-    "sanity");
+  assert(ik->static_field_size() == _field_info->_static_field_size, "sanity");
+  assert(ik->nonstatic_oop_map_count() == _field_info->oop_map_blocks->_nonstatic_oop_map_count,
+         "sanity");
 
   assert(ik->is_instance_klass(), "sanity");
-  assert(ik->size_helper() == _field_info->instance_size, "sanity");
+  assert(ik->size_helper() == _field_info->_instance_size, "sanity");
 
   // Fill in information already parsed
   ik->set_should_verify_class(_need_verify);
 
   // Not yet: supers are done below to support the new subtype-checking fields
-  ik->set_nonstatic_field_size(_field_info->nonstatic_field_size);
-  ik->set_has_nonstatic_fields(_field_info->has_nonstatic_fields);
+  ik->set_nonstatic_field_size(_field_info->_nonstatic_field_size);
+  ik->set_has_nonstatic_fields(_field_info->_has_nonstatic_fields);
   assert(_fac != NULL, "invariant");
   ik->set_static_oop_field_count(_fac->count[STATIC_OOP]);
 
@@ -5755,10 +5745,15 @@
 
   // Compute transitive closure of interfaces this class implements
   // Do final class setup
-  fill_oop_maps(ik,
-                _field_info->nonstatic_oop_map_count,
-                _field_info->nonstatic_oop_offsets,
-                _field_info->nonstatic_oop_counts);
+  OopMapBlocksBuilder* oop_map_blocks = _field_info->oop_map_blocks;
+  if (oop_map_blocks->_nonstatic_oop_map_count > 0) {
+    oop_map_blocks->copy(ik->start_of_nonstatic_oop_maps());
+  }
+
+  if (_has_contended_fields || _parsed_annotations->is_contended() ||
+      ( _super_klass != NULL && _super_klass->has_contended_annotations())) {
+    ik->set_has_contended_annotations(true);
+  }
 
   // Fill in has_finalizer, has_vanilla_constructor, and layout_helper
   set_precomputed_flags(ik);
@@ -6001,6 +5996,7 @@
   _has_nonstatic_concrete_methods(false),
   _declares_nonstatic_concrete_methods(false),
   _has_final_method(false),
+  _has_contended_fields(false),
   _has_finalizer(false),
   _has_empty_finalizer(false),
   _has_vanilla_constructor(false),
@@ -6478,7 +6474,13 @@
   assert(_parsed_annotations != NULL, "invariant");
 
   _field_info = new FieldLayoutInfo();
-  layout_fields(cp, _fac, _parsed_annotations, _field_info, CHECK);
+  if (UseNewFieldLayout) {
+    FieldLayoutBuilder lb(class_name(), super_klass(), _cp, _fields,
+                          _parsed_annotations->is_contended(), _field_info);
+    lb.build_layout();
+  } else {
+    layout_fields(cp, _fac, _parsed_annotations, _field_info, CHECK);
+  }
 
   // Compute reference typ
   _rt = (NULL ==_super_klass) ? REF_NONE : _super_klass->reference_type();
--- a/src/hotspot/share/classfile/classFileParser.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/classfile/classFileParser.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "memory/referenceType.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/instanceKlass.hpp"
 #include "oops/typeArrayOop.hpp"
 #include "utilities/accessFlags.hpp"
 
@@ -45,17 +46,46 @@
 class RecordComponent;
 class Symbol;
 class TempNewSymbol;
+class FieldLayoutBuilder;
+
+// Utility to collect and compact oop maps during layout
+class OopMapBlocksBuilder : public ResourceObj {
+ public:
+  OopMapBlock* _nonstatic_oop_maps;
+  unsigned int _nonstatic_oop_map_count;
+  unsigned int _max_nonstatic_oop_maps;
+
+  OopMapBlocksBuilder(unsigned int  max_blocks);
+  OopMapBlock* last_oop_map() const;
+  void initialize_inherited_blocks(OopMapBlock* blocks, unsigned int nof_blocks);
+  void add(int offset, int count);
+  void copy(OopMapBlock* dst);
+  void compact();
+  void print_on(outputStream* st) const;
+  void print_value_on(outputStream* st) const;
+};
+
+// Values needed for oopmap and InstanceKlass creation
+class FieldLayoutInfo : public ResourceObj {
+ public:
+  OopMapBlocksBuilder* oop_map_blocks;
+  int _instance_size;
+  int _nonstatic_field_size;
+  int _static_field_size;
+  bool  _has_nonstatic_fields;
+};
 
 // Parser for for .class files
 //
 // The bytes describing the class file structure is read from a Stream object
 
 class ClassFileParser {
+  friend class FieldLayoutBuilder;
+  friend class FieldLayout;
 
- class ClassAnnotationCollector;
- class FieldAllocationCount;
- class FieldAnnotationCollector;
- class FieldLayoutInfo;
+  class ClassAnnotationCollector;
+  class FieldAllocationCount;
+  class FieldAnnotationCollector;
 
  public:
   // The ClassFileParser has an associated "publicity" level
@@ -161,6 +191,7 @@
   bool _has_nonstatic_concrete_methods;
   bool _declares_nonstatic_concrete_methods;
   bool _has_final_method;
+  bool _has_contended_fields;
 
   // precomputed flags
   bool _has_finalizer;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "classfile/classFileParser.hpp"
+#include "classfile/fieldLayoutBuilder.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/array.hpp"
+#include "oops/fieldStreams.inline.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+#include "oops/klass.inline.hpp"
+#include "runtime/fieldDescriptor.inline.hpp"
+
+
+LayoutRawBlock::LayoutRawBlock(Kind kind, int size) :
+  _next_block(NULL),
+  _prev_block(NULL),
+  _kind(kind),
+  _offset(-1),
+  _alignment(1),
+  _size(size),
+  _field_index(-1),
+  _is_reference(false) {
+  assert(kind == EMPTY || kind == RESERVED || kind == PADDING || kind == INHERITED,
+         "Otherwise, should use the constructor with a field index argument");
+  assert(size > 0, "Sanity check");
+}
+
+
+LayoutRawBlock::LayoutRawBlock(int index, Kind kind, int size, int alignment, bool is_reference) :
+ _next_block(NULL),
+ _prev_block(NULL),
+ _kind(kind),
+ _offset(-1),
+ _alignment(alignment),
+ _size(size),
+ _field_index(index),
+ _is_reference(is_reference) {
+  assert(kind == REGULAR || kind == FLATTENED || kind == INHERITED,
+         "Other kind do not have a field index");
+  assert(size > 0, "Sanity check");
+  assert(alignment > 0, "Sanity check");
+}
+
+bool LayoutRawBlock::fit(int size, int alignment) {
+  int adjustment = 0;
+  if ((_offset % alignment) != 0) {
+    adjustment = alignment - (_offset % alignment);
+  }
+  return _size >= size + adjustment;
+}
+
+FieldGroup::FieldGroup(int contended_group) :
+  _next(NULL),
+  _primitive_fields(NULL),
+  _oop_fields(NULL),
+  _contended_group(contended_group),  // -1 means no contended group, 0 means default contended group
+  _oop_count(0) {}
+
+void FieldGroup::add_primitive_field(AllFieldStream fs, BasicType type) {
+  int size = type2aelembytes(type);
+  LayoutRawBlock* block = new LayoutRawBlock(fs.index(), LayoutRawBlock::REGULAR, size, size /* alignment == size for primitive types */, false);
+  if (_primitive_fields == NULL) {
+    _primitive_fields = new(ResourceObj::RESOURCE_AREA, mtInternal) GrowableArray<LayoutRawBlock*>(INITIAL_LIST_SIZE);
+  }
+  _primitive_fields->append(block);
+}
+
+void FieldGroup::add_oop_field(AllFieldStream fs) {
+  int size = type2aelembytes(T_OBJECT);
+  LayoutRawBlock* block = new LayoutRawBlock(fs.index(), LayoutRawBlock::REGULAR, size, size /* alignment == size for oops */, true);
+  if (_oop_fields == NULL) {
+    _oop_fields = new(ResourceObj::RESOURCE_AREA, mtInternal) GrowableArray<LayoutRawBlock*>(INITIAL_LIST_SIZE);
+  }
+  _oop_fields->append(block);
+  _oop_count++;
+}
+
+void FieldGroup::sort_by_size() {
+  if (_primitive_fields != NULL) {
+    _primitive_fields->sort(LayoutRawBlock::compare_size_inverted);
+  }
+}
+
+FieldLayout::FieldLayout(Array<u2>* fields, ConstantPool* cp) :
+  _fields(fields),
+  _cp(cp),
+  _blocks(NULL),
+  _start(_blocks),
+  _last(_blocks) {}
+
+void FieldLayout::initialize_static_layout() {
+  _blocks = new LayoutRawBlock(LayoutRawBlock::EMPTY, INT_MAX);
+  _blocks->set_offset(0);
+  _last = _blocks;
+  _start = _blocks;
+  // Note: at this stage, InstanceMirrorKlass::offset_of_static_fields() could be zero, because
+  // during bootstrapping, the size of the java.lang.Class is still not known when layout
+  // of static field is computed. Field offsets are fixed later when the size is known
+  // (see java_lang_Class::fixup_mirror())
+  if (InstanceMirrorKlass::offset_of_static_fields() > 0) {
+    insert(first_empty_block(), new LayoutRawBlock(LayoutRawBlock::RESERVED, InstanceMirrorKlass::offset_of_static_fields()));
+    _blocks->set_offset(0);
+  }
+}
+
+void FieldLayout::initialize_instance_layout(const InstanceKlass* super_klass) {
+  if (super_klass == NULL) {
+    _blocks = new LayoutRawBlock(LayoutRawBlock::EMPTY, INT_MAX);
+    _blocks->set_offset(0);
+    _last = _blocks;
+    _start = _blocks;
+    insert(first_empty_block(), new LayoutRawBlock(LayoutRawBlock::RESERVED, instanceOopDesc::base_offset_in_bytes()));
+  } else {
+    reconstruct_layout(super_klass);
+    fill_holes(super_klass);
+    if (UseEmptySlotsInSupers && !super_klass->has_contended_annotations()) {
+      _start = _blocks; // Setting _start to _blocks instead of _last would allow subclasses
+                        // to allocate fields in empty slots of their super classes
+    } else {
+      _start = _last;
+    }
+  }
+}
+
+LayoutRawBlock* FieldLayout::first_field_block() {
+  LayoutRawBlock* block = _start;
+  while (block->kind() != LayoutRawBlock::INHERITED && block->kind() != LayoutRawBlock::REGULAR
+      && block->kind() != LayoutRawBlock::FLATTENED && block->kind() != LayoutRawBlock::PADDING) {
+    block = block->next_block();
+  }
+  return block;
+}
+
+
+// Insert a set of fields into a layout using a best-fit strategy.
+// For each field, search for the smallest empty slot able to fit the field
+// (satisfying both size and alignment requirements), if none is found,
+// add the field at the end of the layout.
+// Fields cannot be inserted before the block specified in the "start" argument
+void FieldLayout::add(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start) {
+  if (list == NULL) return;
+  if (start == NULL) start = this->_start;
+  bool last_search_success = false;
+  int last_size = 0;
+  int last_alignment = 0;
+  for (int i = 0; i < list->length(); i ++) {
+    LayoutRawBlock* b = list->at(i);
+    LayoutRawBlock* cursor = NULL;
+    LayoutRawBlock* candidate = NULL;
+
+    // if start is the last block, just append the field
+    if (start == last_block()) {
+      candidate = last_block();
+    }
+    // Before iterating over the layout to find an empty slot fitting the field's requirements,
+    // check if the previous field had the same requirements and if the search for a fitting slot
+    // was successful. If the requirements were the same but the search failed, a new search will
+    // fail the same way, so just append the field at the of the layout.
+    else  if (b->size() == last_size && b->alignment() == last_alignment && !last_search_success) {
+      candidate = last_block();
+    } else {
+      // Iterate over the layout to find an empty slot fitting the field's requirements
+      last_size = b->size();
+      last_alignment = b->alignment();
+      cursor = last_block()->prev_block();
+      assert(cursor != NULL, "Sanity check");
+      last_search_success = true;
+      while (cursor != start) {
+        if (cursor->kind() == LayoutRawBlock::EMPTY && cursor->fit(b->size(), b->alignment())) {
+          if (candidate == NULL || cursor->size() < candidate->size()) {
+            candidate = cursor;
+          }
+        }
+        cursor = cursor->prev_block();
+      }
+      if (candidate == NULL) {
+        candidate = last_block();
+        last_search_success = false;
+      }
+      assert(candidate != NULL, "Candidate must not be null");
+      assert(candidate->kind() == LayoutRawBlock::EMPTY, "Candidate must be an empty block");
+      assert(candidate->fit(b->size(), b->alignment()), "Candidate must be able to store the block");
+    }
+
+    insert_field_block(candidate, b);
+  }
+}
+
+// Used for classes with hard coded field offsets, insert a field at the specified offset */
+void FieldLayout::add_field_at_offset(LayoutRawBlock* block, int offset, LayoutRawBlock* start) {
+  assert(block != NULL, "Sanity check");
+  block->set_offset(offset);
+  if (start == NULL) {
+    start = this->_start;
+  }
+  LayoutRawBlock* slot = start;
+  while (slot != NULL) {
+    if ((slot->offset() <= block->offset() && (slot->offset() + slot->size()) > block->offset()) ||
+        slot == _last){
+      assert(slot->kind() == LayoutRawBlock::EMPTY, "Matching slot must be an empty slot");
+      assert(slot->size() >= block->offset() + block->size() ,"Matching slot must be big enough");
+      if (slot->offset() < block->offset()) {
+        int adjustment = block->offset() - slot->offset();
+        LayoutRawBlock* adj = new LayoutRawBlock(LayoutRawBlock::EMPTY, adjustment);
+        insert(slot, adj);
+      }
+      insert(slot, block);
+      if (slot->size() == 0) {
+        remove(slot);
+      }
+      FieldInfo::from_field_array(_fields, block->field_index())->set_offset(block->offset());
+      return;
+    }
+    slot = slot->next_block();
+  }
+  fatal("Should have found a matching slot above, corrupted layout or invalid offset");
+}
+
+// The allocation logic uses a best fit strategy: the set of fields is allocated
+// in the first empty slot big enough to contain the whole set ((including padding
+// to fit alignment constraints).
+void FieldLayout::add_contiguously(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start) {
+  if (list == NULL) return;
+  if (start == NULL) {
+    start = _start;
+  }
+  // This code assumes that if the first block is well aligned, the following
+  // blocks would naturally be well aligned (no need for adjustment)
+  int size = 0;
+  for (int i = 0; i < list->length(); i++) {
+    size += list->at(i)->size();
+  }
+
+  LayoutRawBlock* candidate = NULL;
+  if (start == last_block()) {
+    candidate = last_block();
+  } else {
+    LayoutRawBlock* first = list->at(0);
+    candidate = last_block()->prev_block();
+    while (candidate->kind() != LayoutRawBlock::EMPTY || !candidate->fit(size, first->alignment())) {
+      if (candidate == start) {
+        candidate = last_block();
+        break;
+      }
+      candidate = candidate->prev_block();
+    }
+    assert(candidate != NULL, "Candidate must not be null");
+    assert(candidate->kind() == LayoutRawBlock::EMPTY, "Candidate must be an empty block");
+    assert(candidate->fit(size, first->alignment()), "Candidate must be able to store the whole contiguous block");
+  }
+
+  for (int i = 0; i < list->length(); i++) {
+    LayoutRawBlock* b = list->at(i);
+    insert_field_block(candidate, b);
+    assert((candidate->offset() % b->alignment() == 0), "Contiguous blocks must be naturally well aligned");
+  }
+}
+
+LayoutRawBlock* FieldLayout::insert_field_block(LayoutRawBlock* slot, LayoutRawBlock* block) {
+  assert(slot->kind() == LayoutRawBlock::EMPTY, "Blocks can only be inserted in empty blocks");
+  if (slot->offset() % block->alignment() != 0) {
+    int adjustment = block->alignment() - (slot->offset() % block->alignment());
+    LayoutRawBlock* adj = new LayoutRawBlock(LayoutRawBlock::EMPTY, adjustment);
+    insert(slot, adj);
+  }
+  insert(slot, block);
+  if (slot->size() == 0) {
+    remove(slot);
+  }
+  FieldInfo::from_field_array(_fields, block->field_index())->set_offset(block->offset());
+  return block;
+}
+
+void FieldLayout::reconstruct_layout(const InstanceKlass* ik) {
+  GrowableArray<LayoutRawBlock*>* all_fields = new GrowableArray<LayoutRawBlock*>(32);
+  while (ik != NULL) {
+    for (AllFieldStream fs(ik->fields(), ik->constants()); !fs.done(); fs.next()) {
+      BasicType type = Signature::basic_type(fs.signature());
+      // distinction between static and non-static fields is missing
+      if (fs.access_flags().is_static()) continue;
+      int size = type2aelembytes(type);
+      // INHERITED blocks are marked as non-reference because oop_maps are handled by their holder class
+      LayoutRawBlock* block = new LayoutRawBlock(fs.index(), LayoutRawBlock::INHERITED, size, size, false);
+      block->set_offset(fs.offset());
+      all_fields->append(block);
+    }
+    ik = ik->super() == NULL ? NULL : InstanceKlass::cast(ik->super());
+  }
+
+  all_fields->sort(LayoutRawBlock::compare_offset);
+  _blocks = new LayoutRawBlock(LayoutRawBlock::RESERVED, instanceOopDesc::base_offset_in_bytes());
+  _blocks->set_offset(0);
+  _last = _blocks;
+
+  for(int i = 0; i < all_fields->length(); i++) {
+    LayoutRawBlock* b = all_fields->at(i);
+    _last->set_next_block(b);
+    b->set_prev_block(_last);
+    _last = b;
+  }
+  _start = _blocks;
+}
+
+// Called during the reconstruction of a layout, after fields from super
+// classes have been inserted. It fills unused slots between inserted fields
+// with EMPTY blocks, so the regular field insertion methods would work.
+// This method handles classes with @Contended annotations differently
+// by inserting PADDING blocks instead of EMPTY block to prevent subclasses'
+// fields to interfere with contended fields/classes.
+void FieldLayout::fill_holes(const InstanceKlass* super_klass) {
+  assert(_blocks != NULL, "Sanity check");
+  assert(_blocks->offset() == 0, "first block must be at offset zero");
+  LayoutRawBlock::Kind filling_type = super_klass->has_contended_annotations() ? LayoutRawBlock::PADDING: LayoutRawBlock::EMPTY;
+  LayoutRawBlock* b = _blocks;
+  while (b->next_block() != NULL) {
+    if (b->next_block()->offset() > (b->offset() + b->size())) {
+      int size = b->next_block()->offset() - (b->offset() + b->size());
+      LayoutRawBlock* empty = new LayoutRawBlock(filling_type, size);
+      empty->set_offset(b->offset() + b->size());
+      empty->set_next_block(b->next_block());
+      b->next_block()->set_prev_block(empty);
+      b->set_next_block(empty);
+      empty->set_prev_block(b);
+    }
+    b = b->next_block();
+  }
+  assert(b->next_block() == NULL, "Invariant at this point");
+  assert(b->kind() != LayoutRawBlock::EMPTY, "Sanity check");
+
+  // If the super class has @Contended annotation, a padding block is
+  // inserted at the end to ensure that fields from the subclasses won't share
+  // the cache line of the last field of the contended class
+  if (super_klass->has_contended_annotations()) {
+    LayoutRawBlock* p = new LayoutRawBlock(LayoutRawBlock::PADDING, ContendedPaddingWidth);
+    p->set_offset(b->offset() + b->size());
+    b->set_next_block(p);
+    p->set_prev_block(b);
+    b = p;
+  }
+
+  if (!UseEmptySlotsInSupers) {
+    // Add an empty slots to align fields of the subclass on a heapOopSize boundary
+    // in order to emulate the behavior of the previous algorithm
+    int align = (b->offset() + b->size()) % heapOopSize;
+    if (align != 0) {
+      int sz = heapOopSize - align;
+      LayoutRawBlock* p = new LayoutRawBlock(LayoutRawBlock::EMPTY, sz);
+      p->set_offset(b->offset() + b->size());
+      b->set_next_block(p);
+      p->set_prev_block(b);
+      b = p;
+    }
+  }
+
+  LayoutRawBlock* last = new LayoutRawBlock(LayoutRawBlock::EMPTY, INT_MAX);
+  last->set_offset(b->offset() + b->size());
+  assert(last->offset() > 0, "Sanity check");
+  b->set_next_block(last);
+  last->set_prev_block(b);
+  _last = last;
+}
+
+LayoutRawBlock* FieldLayout::insert(LayoutRawBlock* slot, LayoutRawBlock* block) {
+  assert(slot->kind() == LayoutRawBlock::EMPTY, "Blocks can only be inserted in empty blocks");
+  assert(slot->offset() % block->alignment() == 0, "Incompatible alignment");
+  block->set_offset(slot->offset());
+  slot->set_offset(slot->offset() + block->size());
+  assert((slot->size() - block->size()) < slot->size(), "underflow checking");
+  assert(slot->size() - block->size() >= 0, "no negative size allowed");
+  slot->set_size(slot->size() - block->size());
+  block->set_prev_block(slot->prev_block());
+  block->set_next_block(slot);
+  slot->set_prev_block(block);
+  if (block->prev_block() != NULL) {
+    block->prev_block()->set_next_block(block);
+  }
+  if (_blocks == slot) {
+    _blocks = block;
+  }
+  return block;
+}
+
+void FieldLayout::remove(LayoutRawBlock* block) {
+  assert(block != NULL, "Sanity check");
+  assert(block != _last, "Sanity check");
+  if (_blocks == block) {
+    _blocks = block->next_block();
+    if (_blocks != NULL) {
+      _blocks->set_prev_block(NULL);
+    }
+  } else {
+    assert(block->prev_block() != NULL, "_prev should be set for non-head blocks");
+    block->prev_block()->set_next_block(block->next_block());
+    block->next_block()->set_prev_block(block->prev_block());
+  }
+  if (block == _start) {
+    _start = block->prev_block();
+  }
+}
+
+void FieldLayout::print(outputStream* output, bool is_static, const InstanceKlass* super) {
+  ResourceMark rm;
+  LayoutRawBlock* b = _blocks;
+  while(b != _last) {
+    switch(b->kind()) {
+      case LayoutRawBlock::REGULAR: {
+        FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
+        output->print_cr(" @%d \"%s\" %s %d/%d %s",
+                         b->offset(),
+                         fi->name(_cp)->as_C_string(),
+                         fi->signature(_cp)->as_C_string(),
+                         b->size(),
+                         b->alignment(),
+                         "REGULAR");
+        break;
+      }
+      case LayoutRawBlock::FLATTENED: {
+        FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
+        output->print_cr(" @%d \"%s\" %s %d/%d %s",
+                         b->offset(),
+                         fi->name(_cp)->as_C_string(),
+                         fi->signature(_cp)->as_C_string(),
+                         b->size(),
+                         b->alignment(),
+                         "FLATTENED");
+        break;
+      }
+      case LayoutRawBlock::RESERVED: {
+        output->print_cr(" @%d %d/- %s",
+                         b->offset(),
+                         b->size(),
+                         "RESERVED");
+        break;
+      }
+      case LayoutRawBlock::INHERITED: {
+        assert(!is_static, "Static fields are not inherited in layouts");
+        assert(super != NULL, "super klass must be provided to retrieve inherited fields info");
+        bool found = false;
+        const InstanceKlass* ik = super;
+        while (!found && ik != NULL) {
+          for (AllFieldStream fs(ik->fields(), ik->constants()); !fs.done(); fs.next()) {
+            if (fs.offset() == b->offset()) {
+              output->print_cr(" @%d \"%s\" %s %d/%d %s",
+                  b->offset(),
+                  fs.name()->as_C_string(),
+                  fs.signature()->as_C_string(),
+                  b->size(),
+                  b->size(), // so far, alignment constraint == size, will change with Valhalla
+                  "INHERITED");
+              found = true;
+              break;
+            }
+          }
+          ik = ik->java_super();
+        }
+        break;
+      }
+      case LayoutRawBlock::EMPTY:
+        output->print_cr(" @%d %d/1 %s",
+                         b->offset(),
+                         b->size(),
+                        "EMPTY");
+        break;
+      case LayoutRawBlock::PADDING:
+        output->print_cr(" @%d %d/1 %s",
+                         b->offset(),
+                         b->size(),
+                        "PADDING");
+        break;
+    }
+    b = b->next_block();
+  }
+}
+
+FieldLayoutBuilder::FieldLayoutBuilder(const Symbol* classname, const InstanceKlass* super_klass, ConstantPool* constant_pool,
+      Array<u2>* fields, bool is_contended, FieldLayoutInfo* info) :
+  _classname(classname),
+  _super_klass(super_klass),
+  _constant_pool(constant_pool),
+  _fields(fields),
+  _info(info),
+  _root_group(NULL),
+  _contended_groups(GrowableArray<FieldGroup*>(8)),
+  _static_fields(NULL),
+  _layout(NULL),
+  _static_layout(NULL),
+  _nonstatic_oopmap_count(0),
+  _alignment(-1),
+  _has_nonstatic_fields(false),
+  _is_contended(is_contended) {}
+
+
+FieldGroup* FieldLayoutBuilder::get_or_create_contended_group(int g) {
+  assert(g > 0, "must only be called for named contended groups");
+  FieldGroup* fg = NULL;
+  for (int i = 0; i < _contended_groups.length(); i++) {
+    fg = _contended_groups.at(i);
+    if (fg->contended_group() == g) return fg;
+  }
+  fg = new FieldGroup(g);
+  _contended_groups.append(fg);
+  return fg;
+}
+
+void FieldLayoutBuilder::prologue() {
+  _layout = new FieldLayout(_fields, _constant_pool);
+  const InstanceKlass* super_klass = _super_klass;
+  _layout->initialize_instance_layout(super_klass);
+  if (super_klass != NULL) {
+    _has_nonstatic_fields = super_klass->has_nonstatic_fields();
+  }
+  _static_layout = new FieldLayout(_fields, _constant_pool);
+  _static_layout->initialize_static_layout();
+  _static_fields = new FieldGroup();
+  _root_group = new FieldGroup();
+}
+
+// Field sorting for regular classes:
+//   - fields are sorted in static and non-static fields
+//   - non-static fields are also sorted according to their contention group
+//     (support of the @Contended annotation)
+//   - @Contended annotation is ignored for static fields
+void FieldLayoutBuilder::regular_field_sorting() {
+  for (AllFieldStream fs(_fields, _constant_pool); !fs.done(); fs.next()) {
+    FieldGroup* group = NULL;
+    if (fs.access_flags().is_static()) {
+      group = _static_fields;
+    } else {
+      _has_nonstatic_fields = true;
+      if (fs.is_contended()) {
+        int g = fs.contended_group();
+        if (g == 0) {
+          group = new FieldGroup(true);
+          _contended_groups.append(group);
+        } else {
+          group = get_or_create_contended_group(g);
+        }
+      } else {
+        group = _root_group;
+      }
+    }
+    assert(group != NULL, "invariant");
+    BasicType type = Signature::basic_type(fs.signature());
+    switch(type) {
+      case T_BYTE:
+      case T_CHAR:
+      case T_DOUBLE:
+      case T_FLOAT:
+      case T_INT:
+      case T_LONG:
+      case T_SHORT:
+      case T_BOOLEAN:
+        group->add_primitive_field(fs, type);
+        break;
+      case T_OBJECT:
+      case T_ARRAY:
+        if (group != _static_fields) _nonstatic_oopmap_count++;
+        group->add_oop_field(fs);
+        break;
+      default:
+        fatal("Something wrong?");
+    }
+  }
+  _root_group->sort_by_size();
+  _static_fields->sort_by_size();
+  if (!_contended_groups.is_empty()) {
+    for (int i = 0; i < _contended_groups.length(); i++) {
+      _contended_groups.at(i)->sort_by_size();
+    }
+  }
+}
+
+void FieldLayoutBuilder::insert_contended_padding(LayoutRawBlock* slot) {
+  if (ContendedPaddingWidth > 0) {
+    LayoutRawBlock* padding = new LayoutRawBlock(LayoutRawBlock::PADDING, ContendedPaddingWidth);
+    _layout->insert(slot, padding);
+  }
+}
+
+// Computation of regular classes layout is an evolution of the previous default layout
+// (FieldAllocationStyle 1):
+//   - primitive fields are allocated first (from the biggest to the smallest)
+//   - then oop fields are allocated, either in existing gaps or at the end of
+//     the layout
+void FieldLayoutBuilder::compute_regular_layout() {
+  bool need_tail_padding = false;
+  prologue();
+  regular_field_sorting();
+
+  if (_is_contended) {
+    _layout->set_start(_layout->last_block());
+    // insertion is currently easy because the current strategy doesn't try to fill holes
+    // in super classes layouts => the _start block is by consequence the _last_block
+    insert_contended_padding(_layout->start());
+    need_tail_padding = true;
+  }
+  _layout->add(_root_group->primitive_fields());
+  _layout->add(_root_group->oop_fields());
+
+  if (!_contended_groups.is_empty()) {
+    for (int i = 0; i < _contended_groups.length(); i++) {
+      FieldGroup* cg = _contended_groups.at(i);
+      LayoutRawBlock* start = _layout->last_block();
+      insert_contended_padding(start);
+      _layout->add(cg->primitive_fields(), start);
+      _layout->add(cg->oop_fields(), start);
+      need_tail_padding = true;
+    }
+  }
+
+  if (need_tail_padding) {
+    insert_contended_padding(_layout->last_block());
+  }
+
+  _static_layout->add_contiguously(this->_static_fields->oop_fields());
+  _static_layout->add(this->_static_fields->primitive_fields());
+
+  epilogue();
+}
+
+// Compute layout of the java/lang/ref/Reference class according
+// to the hard coded offsets of its fields
+void FieldLayoutBuilder::compute_java_lang_ref_Reference_layout() {
+  prologue();
+  regular_field_sorting();
+
+  assert(_contended_groups.is_empty(), "java.lang.Reference has no @Contended annotations");
+  assert(_root_group->primitive_fields() == NULL, "java.lang.Reference has no nonstatic primitive fields");
+  int field_count = 0;
+  int offset = -1;
+  for (int i = 0; i < _root_group->oop_fields()->length(); i++) {
+    LayoutRawBlock* b = _root_group->oop_fields()->at(i);
+    FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
+    if (fi->name(_constant_pool)->equals("referent")) {
+      offset = java_lang_ref_Reference::referent_offset;
+    } else if (fi->name(_constant_pool)->equals("queue")) {
+      offset = java_lang_ref_Reference::queue_offset;
+    } else if (fi->name(_constant_pool)->equals("next")) {
+      offset = java_lang_ref_Reference::next_offset;
+    } else if (fi->name(_constant_pool)->equals("discovered")) {
+      offset = java_lang_ref_Reference::discovered_offset;
+    }
+    assert(offset != -1, "Unknown field");
+    _layout->add_field_at_offset(b, offset);
+    field_count++;
+  }
+  assert(field_count == 4, "Wrong number of fields in java.lang.ref.Reference");
+
+  _static_layout->add_contiguously(this->_static_fields->oop_fields());
+  _static_layout->add(this->_static_fields->primitive_fields());
+
+  epilogue();
+}
+
+// Compute layout of the boxing class according
+// to the hard coded offsets of their fields
+void FieldLayoutBuilder::compute_boxing_class_layout() {
+  prologue();
+  regular_field_sorting();
+
+  assert(_contended_groups.is_empty(), "Boxing classes have no @Contended annotations");
+  assert(_root_group->oop_fields() == NULL, "Boxing classes have no nonstatic oops fields");
+  int field_count = 0;
+  int offset = -1;
+
+  for (int i = 0; i < _root_group->primitive_fields()->length(); i++) {
+    LayoutRawBlock* b = _root_group->primitive_fields()->at(i);
+    FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
+    assert(fi->name(_constant_pool)->equals("value"), "Boxing classes have a single nonstatic field named 'value'");
+    BasicType type = Signature::basic_type(fi->signature(_constant_pool));
+    offset = java_lang_boxing_object::value_offset_in_bytes(type);
+    assert(offset != -1, "Unknown field");
+    _layout->add_field_at_offset(b, offset);
+    field_count++;
+  }
+  assert(field_count == 1, "Wrong number of fields for a boxing class");
+
+  _static_layout->add_contiguously(this->_static_fields->oop_fields());
+  _static_layout->add(this->_static_fields->primitive_fields());
+
+  epilogue();
+}
+
+void FieldLayoutBuilder::epilogue() {
+  // Computing oopmaps
+  int super_oop_map_count = (_super_klass == NULL) ? 0 :_super_klass->nonstatic_oop_map_count();
+  int max_oop_map_count = super_oop_map_count + _nonstatic_oopmap_count;
+
+  OopMapBlocksBuilder* nonstatic_oop_maps =
+      new OopMapBlocksBuilder(max_oop_map_count);
+  if (super_oop_map_count > 0) {
+    nonstatic_oop_maps->initialize_inherited_blocks(_super_klass->start_of_nonstatic_oop_maps(),
+    _super_klass->nonstatic_oop_map_count());
+  }
+
+  if (_root_group->oop_fields() != NULL) {
+    for (int i = 0; i < _root_group->oop_fields()->length(); i++) {
+      LayoutRawBlock* b = _root_group->oop_fields()->at(i);
+      nonstatic_oop_maps->add(b->offset(), 1);
+    }
+  }
+
+  if (!_contended_groups.is_empty()) {
+    for (int i = 0; i < _contended_groups.length(); i++) {
+      FieldGroup* cg = _contended_groups.at(i);
+      if (cg->oop_count() > 0) {
+        assert(cg->oop_fields() != NULL && cg->oop_fields()->at(0) != NULL, "oop_count > 0 but no oop fields found");
+        nonstatic_oop_maps->add(cg->oop_fields()->at(0)->offset(), cg->oop_count());
+      }
+    }
+  }
+
+  nonstatic_oop_maps->compact();
+
+  int instance_end = align_up(_layout->last_block()->offset(), wordSize);
+  int static_fields_end = align_up(_static_layout->last_block()->offset(), wordSize);
+  int static_fields_size = (static_fields_end -
+      InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
+  int nonstatic_field_end = align_up(_layout->last_block()->offset(), heapOopSize);
+
+  // Pass back information needed for InstanceKlass creation
+
+  _info->oop_map_blocks = nonstatic_oop_maps;
+  _info->_instance_size = align_object_size(instance_end / wordSize);
+  _info->_static_field_size = static_fields_size;
+  _info->_nonstatic_field_size = (nonstatic_field_end - instanceOopDesc::base_offset_in_bytes()) / heapOopSize;
+  _info->_has_nonstatic_fields = _has_nonstatic_fields;
+
+  if (PrintFieldLayout) {
+    ResourceMark rm;
+    tty->print_cr("Layout of class %s", _classname->as_C_string());
+    tty->print_cr("Instance fields:");
+    _layout->print(tty, false, _super_klass);
+    tty->print_cr("Static fields:");
+    _static_layout->print(tty, true, NULL);
+    tty->print_cr("Instance size = %d bytes", _info->_instance_size * wordSize);
+    tty->print_cr("---");
+  }
+}
+
+void FieldLayoutBuilder::build_layout() {
+  if (_classname == vmSymbols::java_lang_ref_Reference()) {
+    compute_java_lang_ref_Reference_layout();
+  } else if (_classname == vmSymbols::java_lang_Boolean() ||
+             _classname == vmSymbols::java_lang_Character() ||
+             _classname == vmSymbols::java_lang_Float() ||
+             _classname == vmSymbols::java_lang_Double() ||
+             _classname == vmSymbols::java_lang_Byte() ||
+             _classname == vmSymbols::java_lang_Short() ||
+             _classname == vmSymbols::java_lang_Integer() ||
+             _classname == vmSymbols::java_lang_Long()) {
+    compute_boxing_class_layout();
+  } else {
+    compute_regular_layout();
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/fieldLayoutBuilder.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_CLASSFILE_FIELDLAYOUTBUILDER_HPP
+#define SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
+
+#include "classfile/classFileParser.hpp"
+#include "classfile/classLoaderData.hpp"
+#include "memory/allocation.hpp"
+#include "oops/fieldStreams.hpp"
+#include "utilities/growableArray.hpp"
+
+// Classes below are used to compute the field layout of classes.
+
+
+// A LayoutRawBlock describes an element of a layout.
+// Each field is represented by a LayoutRawBlock.
+// LayoutRawBlocks can also represent elements injected by the JVM:
+// padding, empty blocks, inherited fields, etc.
+// All LayoutRawBlocks must have a size and an alignment. The size is the
+// exact size of the field expressed in bytes. The alignment is
+// the alignment constraint of the field (1 for byte, 2 for short,
+// 4 for int, 8 for long, etc.)
+//
+// LayoutRawBlock are designed to be used in two data structures:
+//   - a linked list in a layout (using _next_block, _prev_block)
+//   - a GrowableArray in field group (the growable array contains pointers to LayoutRawBlocks)
+//
+//  next/prev pointers are included in the LayoutRawBlock class to narrow
+//  the number of allocation required during the computation of a layout.
+//
+class LayoutRawBlock : public ResourceObj {
+ public:
+  // Some code relies on the order of values below.
+  enum Kind {
+    EMPTY,         // empty slot, space is taken from this to allocate fields
+    RESERVED,      // reserved for JVM usage (for instance object header)
+    PADDING,       // padding (because of alignment constraints or @Contended)
+    REGULAR,       // primitive or oop field (including non-flattened inline fields)
+    FLATTENED,     // flattened field
+    INHERITED      // field(s) inherited from super classes
+  };
+
+ private:
+  LayoutRawBlock* _next_block;
+  LayoutRawBlock* _prev_block;
+  Kind _kind;
+  int _offset;
+  int _alignment;
+  int _size;
+  int _field_index;
+  bool _is_reference;
+
+ public:
+  LayoutRawBlock(Kind kind, int size);
+  LayoutRawBlock(int index, Kind kind, int size, int alignment, bool is_reference = false);
+  LayoutRawBlock* next_block() const { return _next_block; }
+  void set_next_block(LayoutRawBlock* next) { _next_block = next; }
+  LayoutRawBlock* prev_block() const { return _prev_block; }
+  void set_prev_block(LayoutRawBlock* prev) { _prev_block = prev; }
+  Kind kind() const { return _kind; }
+  int offset() const {
+    assert(_offset >= 0, "Must be initialized");
+    return _offset;
+  }
+  void set_offset(int offset) { _offset = offset; }
+  int alignment() const { return _alignment; }
+  int size() const { return _size; }
+  void set_size(int size) { _size = size; }
+  int field_index() const {
+    assert(_field_index != -1, "Must be initialized");
+    return _field_index;
+  }
+  bool is_reference() const { return _is_reference; }
+
+  bool fit(int size, int alignment);
+
+  static int compare_offset(LayoutRawBlock** x, LayoutRawBlock** y)  { return (*x)->offset() - (*y)->offset(); }
+  // compare_size_inverted() returns the opposite of a regular compare method in order to
+  // sort fields in decreasing order.
+  // Note: with line types, the comparison should include alignment constraint if sizes are equals
+  static int compare_size_inverted(LayoutRawBlock** x, LayoutRawBlock** y)  {
+#ifdef _WINDOWS
+    // qsort() on Windows reverse the order of fields with the same size
+    // the extension of the comparison function below preserves this order
+    int diff = (*y)->size() - (*x)->size();
+    if (diff == 0) {
+      diff = (*x)->field_index() - (*y)->field_index();
+    }
+    return diff;
+#else
+    return (*y)->size() - (*x)->size();
+#endif // _WINDOWS
+  }
+
+};
+
+// A Field group represents a set of fields that have to be allocated together,
+// this is the way the @Contended annotation is supported.
+// Inside a FieldGroup, fields are sorted based on their kind: primitive,
+// oop, or flattened.
+//
+class FieldGroup : public ResourceObj {
+
+ private:
+  FieldGroup* _next;
+  GrowableArray<LayoutRawBlock*>* _primitive_fields;
+  GrowableArray<LayoutRawBlock*>* _oop_fields;
+  int _contended_group;
+  int _oop_count;
+  static const int INITIAL_LIST_SIZE = 16;
+
+ public:
+  FieldGroup(int contended_group = -1);
+
+  FieldGroup* next() const { return _next; }
+  void set_next(FieldGroup* next) { _next = next; }
+  GrowableArray<LayoutRawBlock*>* primitive_fields() const { return _primitive_fields; }
+  GrowableArray<LayoutRawBlock*>* oop_fields() const { return _oop_fields; }
+  int contended_group() const { return _contended_group; }
+  int oop_count() const { return _oop_count; }
+
+  void add_primitive_field(AllFieldStream fs, BasicType type);
+  void add_oop_field(AllFieldStream fs);
+  void sort_by_size();
+};
+
+// The FieldLayout class represents a set of fields organized
+// in a layout.
+// An instance of FieldLayout can either represent the layout
+// of non-static fields (used in an instance object) or the
+// layout of static fields (to be included in the class mirror).
+//
+// _block is a pointer to a list of LayoutRawBlock ordered by increasing
+// offsets.
+// _start points to the LayoutRawBlock with the first offset that can
+// be used to allocate fields of the current class
+// _last points to the last LayoutRawBlock of the list. In order to
+// simplify the code, the LayoutRawBlock list always ends with an
+// EMPTY block (the kind of LayoutRawBlock from which space is taken
+// to allocate fields) with a size big enough to satisfy all
+// field allocations.
+//
+class FieldLayout : public ResourceObj {
+ private:
+  Array<u2>* _fields;
+  ConstantPool* _cp;
+  LayoutRawBlock* _blocks;  // the layout being computed
+  LayoutRawBlock* _start;   // points to the first block where a field can be inserted
+  LayoutRawBlock* _last;    // points to the last block of the layout (big empty block)
+
+ public:
+  FieldLayout(Array<u2>* fields, ConstantPool* cp);
+  void initialize_static_layout();
+  void initialize_instance_layout(const InstanceKlass* ik);
+
+  LayoutRawBlock* first_empty_block() {
+    LayoutRawBlock* block = _start;
+    while (block->kind() != LayoutRawBlock::EMPTY) {
+      block = block->next_block();
+    }
+    return block;
+  }
+
+  LayoutRawBlock* start() { return _start; }
+  void set_start(LayoutRawBlock* start) { _start = start; }
+  LayoutRawBlock* last_block() { return _last; }
+
+  LayoutRawBlock* first_field_block();
+  void add(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = NULL);
+  void add_field_at_offset(LayoutRawBlock* blocks, int offset, LayoutRawBlock* start = NULL);
+  void add_contiguously(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = NULL);
+  LayoutRawBlock* insert_field_block(LayoutRawBlock* slot, LayoutRawBlock* block);
+  void reconstruct_layout(const InstanceKlass* ik);
+  void fill_holes(const InstanceKlass* ik);
+  LayoutRawBlock* insert(LayoutRawBlock* slot, LayoutRawBlock* block);
+  void remove(LayoutRawBlock* block);
+  void print(outputStream* output, bool is_static, const InstanceKlass* super);
+};
+
+
+// FieldLayoutBuilder is the main entry point for layout computation.
+// This class has three methods to generate layout: one for regular classes
+// and two for classes with hard coded offsets (java,lang.ref.Reference
+// and the boxing classes). The rationale for having multiple methods
+// is that each kind of class has a different set goals regarding
+// its layout, so instead of mixing several layout strategies into a
+// single method, each kind has its own method (see comments below
+// for more details about the allocation strategies).
+//
+// Computing the layout of a class always goes through 4 steps:
+//   1 - Prologue: preparation of data structure and gathering of
+//       layout information inherited from super classes
+//   2 - Field sorting: fields are sorted according to their
+//       kind (oop, primitive, inline class) and their contention
+//       annotation (if any)
+//   3 - Layout is computed from the set of lists generated during
+//       step 2
+//   4 - Epilogue: oopmaps are generated, layout information is
+//       prepared so other VM components can use it (instance size,
+//       static field size, non-static field size, etc.)
+//
+//  Steps 1 and 4 are common to all layout computations. Step 2 and 3
+//  can vary with the allocation strategy.
+//
+class FieldLayoutBuilder : public ResourceObj {
+ private:
+
+  const Symbol* _classname;
+  const InstanceKlass* _super_klass;
+  ConstantPool* _constant_pool;
+  Array<u2>* _fields;
+  FieldLayoutInfo* _info;
+  FieldGroup* _root_group;
+  GrowableArray<FieldGroup*> _contended_groups;
+  FieldGroup* _static_fields;
+  FieldLayout* _layout;
+  FieldLayout* _static_layout;
+  int _nonstatic_oopmap_count;
+  int _alignment;
+  bool _has_nonstatic_fields;
+  bool _is_contended; // is a contended class?
+
+ public:
+  FieldLayoutBuilder(const Symbol* classname, const InstanceKlass* super_klass, ConstantPool* constant_pool,
+                     Array<u2>* fields, bool is_contended, FieldLayoutInfo* info);
+
+  int get_alignment() {
+    assert(_alignment != -1, "Uninitialized");
+    return _alignment;
+  }
+
+  void build_layout();
+  void compute_regular_layout();
+  void compute_java_lang_ref_Reference_layout();
+  void compute_boxing_class_layout();
+  void insert_contended_padding(LayoutRawBlock* slot);
+
+ private:
+  void prologue();
+  void epilogue();
+  void regular_field_sorting();
+  FieldGroup* get_or_create_contended_group(int g);
+};
+
+#endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -740,6 +740,9 @@
 }
 
 Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) const {
+  if (c == NULL) {
+    return c;
+  }
   if (c->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
     return c->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
   }
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -58,6 +58,11 @@
         return false;
       }
       C->clear_major_progress();
+      if (C->range_check_cast_count() > 0) {
+        // No more loop optimizations. Remove all range check dependent CastIINodes.
+        C->remove_range_check_casts(igvn);
+        igvn.optimize();
+      }
     }
   }
   return true;
@@ -2009,21 +2014,22 @@
       if (loop != phase->ltree_root() &&
           loop->_child == NULL &&
           !loop->_irreducible) {
-        LoopNode* head = loop->_head->as_Loop();
-        if ((!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) &&
+        Node* head = loop->_head;
+        if (head->is_Loop() &&
+            (!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) &&
             !seen.test_set(head->_idx)) {
           IfNode* iff = find_unswitching_candidate(loop, phase);
           if (iff != NULL) {
             Node* bol = iff->in(1);
-            if (head->is_strip_mined()) {
-              head->verify_strip_mined(0);
+            if (head->as_Loop()->is_strip_mined()) {
+              head->as_Loop()->verify_strip_mined(0);
             }
             move_heap_stable_test_out_of_loop(iff, phase);
 
             AutoNodeBudget node_budget(phase);
 
             if (loop->policy_unswitching(phase)) {
-              if (head->is_strip_mined()) {
+              if (head->as_Loop()->is_strip_mined()) {
                 OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop();
                 hide_strip_mined_loop(outer, head->as_CountedLoop(), phase);
               }
@@ -2291,7 +2297,12 @@
         if (in_opc == Op_Return || in_opc == Op_Rethrow) {
           mem = in->in(TypeFunc::Memory);
         } else if (in_opc == Op_Halt) {
-          if (!in->in(0)->is_Region()) {
+          if (in->in(0)->is_Region()) {
+            Node* r = in->in(0);
+            for (uint j = 1; j < r->req(); j++) {
+              assert(r->in(j)->Opcode() != Op_NeverBranch, "");
+            }
+          } else {
             Node* proj = in->in(0);
             assert(proj->is_Proj(), "");
             Node* in = proj->in(0);
@@ -2303,25 +2314,37 @@
               assert(call->is_Call(), "");
               mem = call->in(TypeFunc::Memory);
             } else if (in->Opcode() == Op_NeverBranch) {
-              ResourceMark rm;
-              Unique_Node_List wq;
-              wq.push(in);
-              wq.push(in->as_Multi()->proj_out(0));
-              for (uint j = 1; j < wq.size(); j++) {
-                Node* c = wq.at(j);
-                assert(!c->is_Root(), "shouldn't leave loop");
-                if (c->is_SafePoint()) {
-                  assert(mem == NULL, "only one safepoint");
+              Node* head = in->in(0);
+              assert(head->is_Region() && head->req() == 3, "unexpected infinite loop graph shape");
+              assert(_phase->is_dominator(head, head->in(1)) || _phase->is_dominator(head, head->in(2)), "no back branch?");
+              Node* tail = _phase->is_dominator(head, head->in(1)) ? head->in(1) : head->in(2);
+              Node* c = tail;
+              while (c != head) {
+                if (c->is_SafePoint() && !c->is_CallLeaf()) {
                   mem = c->in(TypeFunc::Memory);
                 }
-                for (DUIterator_Fast kmax, k = c->fast_outs(kmax); k < kmax; k++) {
-                  Node* u = c->fast_out(k);
-                  if (u->is_CFG()) {
-                    wq.push(u);
+                c = _phase->idom(c);
+              }
+              assert(mem != NULL, "should have found safepoint");
+
+              Node* phi_mem = NULL;
+              for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
+                Node* u = head->fast_out(j);
+                if (u->is_Phi() && u->bottom_type() == Type::MEMORY) {
+                  if (_phase->C->get_alias_index(u->adr_type()) == _alias) {
+                    assert(phi_mem == NULL || phi_mem->adr_type() == TypePtr::BOTTOM, "");
+                    phi_mem = u;
+                  } else if (u->adr_type() == TypePtr::BOTTOM) {
+                    assert(phi_mem == NULL || _phase->C->get_alias_index(phi_mem->adr_type()) == _alias, "");
+                    if (phi_mem == NULL) {
+                      phi_mem = u;
+                    }
                   }
                 }
               }
-              assert(mem != NULL, "should have found safepoint");
+              if (phi_mem != NULL) {
+                mem = phi_mem;
+              }
             }
           }
         } else {
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -435,7 +435,7 @@
 
 void JfrThreadSampler::enroll() {
   if (_disenrolled) {
-    log_info(jfr)("Enrolling thread sampler");
+    log_trace(jfr)("Enrolling thread sampler");
     _sample.signal();
     _disenrolled = false;
   }
@@ -445,7 +445,7 @@
   if (!_disenrolled) {
     _sample.wait();
     _disenrolled = true;
-    log_info(jfr)("Disenrolling thread sampler");
+    log_trace(jfr)("Disenrolling thread sampler");
   }
 }
 
@@ -583,12 +583,12 @@
 }
 
 static void log(size_t interval_java, size_t interval_native) {
-  log_info(jfr)("Updated thread sampler for java: " SIZE_FORMAT "  ms, native " SIZE_FORMAT " ms", interval_java, interval_native);
+  log_trace(jfr)("Updated thread sampler for java: " SIZE_FORMAT "  ms, native " SIZE_FORMAT " ms", interval_java, interval_native);
 }
 
 void JfrThreadSampling::start_sampler(size_t interval_java, size_t interval_native) {
   assert(_sampler == NULL, "invariant");
-  log_info(jfr)("Enrolling thread sampler");
+  log_trace(jfr)("Enrolling thread sampler");
   _sampler = new JfrThreadSampler(interval_java, interval_native, JfrOptionSet::stackdepth());
   _sampler->start_thread();
   _sampler->enroll();
@@ -608,7 +608,7 @@
   }
   if (interval_java > 0 || interval_native > 0) {
     if (_sampler == NULL) {
-      log_info(jfr)("Creating thread sampler for java:%zu ms, native %zu ms", interval_java, interval_native);
+      log_trace(jfr)("Creating thread sampler for java:%zu ms, native %zu ms", interval_java, interval_native);
       start_sampler(interval_java, interval_native);
     } else {
       _sampler->set_java_interval(interval_java);
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -157,7 +157,7 @@
   nonstatic_field(InstanceKlass,               _constants,                                    ConstantPool*)                         \
   nonstatic_field(InstanceKlass,               _source_file_name_index,                       u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
-  nonstatic_field(InstanceKlass,               _misc_flags,                                   u2)                                    \
+  nonstatic_field(InstanceKlass,               _misc_flags,                                   u4)                                    \
   nonstatic_field(InstanceKlass,               _annotations,                                  Annotations*)                          \
                                                                                                                                      \
   volatile_nonstatic_field(JavaFrameAnchor,    _last_Java_sp,                                 intptr_t*)                             \
--- a/src/hotspot/share/oops/fieldStreams.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/oops/fieldStreams.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,6 @@
   fieldDescriptor     _fd_buf;
 
   FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); }
-  InstanceKlass* field_holder() const { return _constants->pool_holder(); }
 
   int init_generic_signature_start_slot() {
     int length = _fields->length();
@@ -87,6 +86,7 @@
 
   // accessors
   int index() const                 { return _index; }
+  InstanceKlass* field_holder() const { return _constants->pool_holder(); }
 
   void next() {
     if (access_flags().field_has_generic_signature()) {
--- a/src/hotspot/share/oops/instanceKlass.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1399,6 +1399,10 @@
   oop_map_cache->lookup(method, bci, entry_for);
 }
 
+bool InstanceKlass::contains_field_offset(int offset) {
+  fieldDescriptor fd;
+  return find_field_from_offset(offset, false, &fd);
+}
 
 bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -103,12 +103,28 @@
   uint count() const         { return _count; }
   void set_count(uint count) { _count = count; }
 
+  void increment_count(int diff) { _count += diff; }
+
+  int offset_span() const { return _count * heapOopSize; }
+
+  int end_offset() const {
+    return offset() + offset_span();
+  }
+
+  bool is_contiguous(int another_offset) const {
+    return another_offset == end_offset();
+  }
+
   // sizeof(OopMapBlock) in words.
   static const int size_in_words() {
     return align_up((int)sizeof(OopMapBlock), wordSize) >>
       LogBytesPerWord;
   }
 
+  static int compare_offset(const OopMapBlock* a, const OopMapBlock* b) {
+    return a->offset() - b->offset();
+  }
+
  private:
   int  _offset;
   uint _count;
@@ -212,7 +228,6 @@
   // _is_marked_dependent can be set concurrently, thus cannot be part of the
   // _misc_flags.
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
-  bool            _is_being_redefined;   // used for locking redefinition
 
   // The low two bits of _misc_flags contains the kind field.
   // This can be used to quickly discriminate among the four kinds of
@@ -243,12 +258,14 @@
     _misc_is_shared_boot_class                = 1 << 12, // defining class loader is boot class loader
     _misc_is_shared_platform_class            = 1 << 13, // defining class loader is platform class loader
     _misc_is_shared_app_class                 = 1 << 14, // defining class loader is app class loader
-    _misc_has_resolved_methods                = 1 << 15  // resolved methods table entries added for this class
+    _misc_has_resolved_methods                = 1 << 15, // resolved methods table entries added for this class
+    _misc_is_being_redefined                  = 1 << 16, // used for locking redefinition
+    _misc_has_contended_annotations           = 1 << 17  // has @Contended annotation
   };
   u2 loader_type_bits() {
     return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
   }
-  u2              _misc_flags;
+  u4              _misc_flags;
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recursive initialization)
@@ -571,9 +588,7 @@
   Klass* find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const;
 
   // find a non-static or static field given its offset within the class.
-  bool contains_field_offset(int offset) {
-    return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size());
-  }
+  bool contains_field_offset(int offset);
 
   bool find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
   bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
@@ -735,10 +750,29 @@
     _nonstatic_oop_map_size = words;
   }
 
+  bool has_contended_annotations() const {
+    return ((_misc_flags & _misc_has_contended_annotations) != 0);
+  }
+  void set_has_contended_annotations(bool value)  {
+    if (value) {
+      _misc_flags |= _misc_has_contended_annotations;
+    } else {
+      _misc_flags &= ~_misc_has_contended_annotations;
+    }
+  }
+
 #if INCLUDE_JVMTI
   // Redefinition locking.  Class can only be redefined by one thread at a time.
-  bool is_being_redefined() const          { return _is_being_redefined; }
-  void set_is_being_redefined(bool value)  { _is_being_redefined = value; }
+  bool is_being_redefined() const          {
+    return ((_misc_flags & _misc_is_being_redefined) != 0);
+  }
+  void set_is_being_redefined(bool value)  {
+    if (value) {
+      _misc_flags |= _misc_is_being_redefined;
+    } else {
+      _misc_flags &= ~_misc_is_being_redefined;
+    }
+  }
 
   // RedefineClasses() support for previous versions:
   void add_previous_version(InstanceKlass* ik, int emcp_method_count);
--- a/src/hotspot/share/oops/instanceOop.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/oops/instanceOop.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,12 +43,6 @@
              klass_gap_offset_in_bytes() :
              sizeof(instanceOopDesc);
   }
-
-  static bool contains_field_offset(int offset, int nonstatic_field_size) {
-    int base_in_bytes = base_offset_in_bytes();
-    return (offset >= base_in_bytes &&
-            (offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
-  }
 };
 
 #endif // SHARE_OOPS_INSTANCEOOP_HPP
--- a/src/hotspot/share/runtime/arguments.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/runtime/arguments.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -522,6 +522,8 @@
   { "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
   { "FlightRecorder",               JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
   { "MonitorBound",                 JDK_Version::jdk(14), JDK_Version::jdk(15), JDK_Version::jdk(16) },
+  { "PrintVMQWaitTime",             JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "UseNewFieldLayout",            JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
 
   // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
   { "DefaultMaxRAMFraction",        JDK_Version::jdk(8),  JDK_Version::undefined(), JDK_Version::undefined() },
--- a/src/hotspot/share/runtime/deoptimization.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -1156,18 +1156,18 @@
 // Restore fields of an eliminated instance object using the same field order
 // returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
 static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal) {
-  if (klass->superklass() != NULL) {
-    svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal);
-  }
-
   GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
-  for (AllFieldStream fs(klass); !fs.done(); fs.next()) {
-    if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) {
-      ReassignedField field;
-      field._offset = fs.offset();
-      field._type = Signature::basic_type(fs.signature());
-      fields->append(field);
+  InstanceKlass* ik = klass;
+  while (ik != NULL) {
+    for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
+      if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) {
+        ReassignedField field;
+        field._offset = fs.offset();
+        field._type = Signature::basic_type(fs.signature());
+        fields->append(field);
+      }
     }
+    ik = ik->superklass();
   }
   fields->sort(compare);
   for (int i = 0; i < fields->length(); i++) {
--- a/src/hotspot/share/runtime/globals.hpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/runtime/globals.hpp	Tue Feb 11 13:41:48 2020 +0530
@@ -267,7 +267,7 @@
           "compilation")                                                    \
                                                                             \
   product(bool, PrintVMQWaitTime, false,                                    \
-          "Print out the waiting time in VM operation queue")               \
+          "(Deprecated) Print out the waiting time in VM operation queue")  \
                                                                             \
   product(bool, MethodFlushing, true,                                       \
           "Reclamation of zombie and not-entrant methods")                  \
@@ -2488,7 +2488,15 @@
           "Start flight recording with options"))                           \
                                                                             \
   experimental(bool, UseFastUnorderedTimeStamps, false,                     \
-          "Use platform unstable time where supported for timestamps only")
+          "Use platform unstable time where supported for timestamps only") \
+                                                                            \
+  product(bool, UseNewFieldLayout, true,                                    \
+               "(Deprecated) Use new algorithm to compute field layouts")   \
+                                                                            \
+  product(bool, UseEmptySlotsInSupers, true,                                \
+                "Allow allocating fields in empty slots of super-classes")  \
+                                                                            \
+
 
 // Interface macros
 #define DECLARE_PRODUCT_FLAG(type, name, value, doc)      extern "C" type name;
--- a/src/hotspot/share/runtime/vmStructs.cpp	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Tue Feb 11 13:41:48 2020 +0530
@@ -235,7 +235,7 @@
   nonstatic_field(InstanceKlass,               _static_oop_field_count,                       u2)                                    \
   nonstatic_field(InstanceKlass,               _nonstatic_oop_map_size,                       int)                                   \
   nonstatic_field(InstanceKlass,               _is_marked_dependent,                          bool)                                  \
-  nonstatic_field(InstanceKlass,               _misc_flags,                                   u2)                                    \
+  nonstatic_field(InstanceKlass,               _misc_flags,                                   u4)                                    \
   nonstatic_field(InstanceKlass,               _minor_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _major_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
--- a/src/java.base/share/classes/java/lang/Module.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/java/lang/Module.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1094,13 +1094,14 @@
 
         // map each module to a class loader
         ClassLoader pcl = ClassLoaders.platformClassLoader();
+        boolean isModuleLoaderMapper = ModuleLoaderMap.isBuiltinMapper(clf);
 
         for (int index = 0; index < numModules; index++) {
             String name = resolvedModules[index].name();
             ClassLoader loader = clf.apply(name);
 
             if (loader == null || loader == pcl) {
-                if (!(clf instanceof ModuleLoaderMap.Mapper)) {
+                if (!isModuleLoaderMapper) {
                     throw new IllegalArgumentException("loader can't be 'null'"
                             + " or the platform class loader");
                 }
--- a/src/java.base/share/classes/java/lang/Record.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/java/lang/Record.java	Tue Feb 11 13:41:48 2020 +0530
@@ -109,7 +109,7 @@
      * @implSpec
      * The implicitly provided implementation returns {@code true} if
      * and only if the argument is an instance of the same record type
-     * as this object, and each component of this record is equal to
+     * as this record, and each component of this record is equal to
      * the corresponding component of the argument; otherwise, {@code
      * false} is returned. Equality of a component {@code c} is
      * determined as follows:
@@ -130,46 +130,70 @@
      *
      * </ul>
      *
-     * The implicitly provided implementation conforms to the
-     * semantics described above; the implementation may or may not
-     * accomplish this by using calls to the particular methods
-     * listed.
+     * Apart from the semantics described above, the precise algorithm
+     * used in the implicitly provided implementation is unspecified
+     * and is subject to change. The implementation may or may not use
+     * calls to the particular methods listed, and may or may not
+     * perform comparisons in the order of component declaration.
      *
      * @see java.util.Objects#equals(Object,Object)
      *
      * @param   obj   the reference object with which to compare.
-     * @return  {@code true} if this object is equal to the
+     * @return  {@code true} if this record is equal to the
      *          argument; {@code false} otherwise.
      */
     @Override
     public abstract boolean equals(Object obj);
 
     /**
+     * Returns a hash code value for the record.
      * Obeys the general contract of {@link Object#hashCode Object.hashCode}.
+     * For records, hashing behavior is constrained by the refined contract
+     * of {@link Record#equals Record.equals}, so that any two records
+     * created from the same components must have the same hash code.
      *
      * @implSpec
      * The implicitly provided implementation returns a hash code value derived
-     * by combining the hash code value for all the components, according to
-     * {@link Object#hashCode()} for components whose types are reference types,
-     * or the primitive wrapper hash code for components whose types are primitive
-     * types.
+     * by combining appropriate hashes from each component.
+     * The precise algorithm used in the implicitly provided implementation
+     * is unspecified and is subject to change within the above limits.
+     * The resulting integer need not remain consistent from one
+     * execution of an application to another execution of the same
+     * application, even if the hashes of the component values were to
+     * remain consistent in this way.  Also, a component of primitive
+     * type may contribute its bits to the hash code differently than
+     * the {@code hashCode} of its primitive wrapper class.
      *
      * @see     Object#hashCode()
      *
-     * @return  a hash code value for this object.
+     * @return  a hash code value for this record.
      */
     @Override
     public abstract int hashCode();
 
     /**
-     * Obeys the general contract of {@link Object#toString Object.toString}.
+     * Returns a string representation of the record.
+     * In accordance with the general contract of {@link Object#toString()},
+     * the {@code toString} method returns a string that
+     * "textually represents" this record. The result should
+     * be a concise but informative representation that is easy for a
+     * person to read.
+     * <p>
+     * In addition to this general contract, record classes must further
+     * participate in the invariant that any two records which are
+     * {@linkplain Record#equals(Object) equal} must produce equal
+     * strings.  This invariant is necessarily relaxed in the rare
+     * case where corresponding equal component values might fail
+     * to produce equal strings for themselves.
      *
      * @implSpec
-     * The implicitly provided implementation returns a string that is derived
-     * from the name of the record class and the names and string representations
-     * of all the components, according to {@link Object#toString()} for components
-     * whose types are reference types, and the primitive wrapper {@code toString}
-     * method for components whose types are primitive types.
+     * The implicitly provided implementation returns a string which
+     * contains the name of the record class, the names of components
+     * of the record, and string representations of component values,
+     * so as to fulfill the contract of this method.
+     * The precise format produced by this implicitly provided implementation
+     * is subject to change, so the present syntax should not be parsed
+     * by applications to recover record component values.
      *
      * @see     Object#toString()
      *
--- a/src/java.base/share/classes/java/lang/module/ResolvedModule.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/java/lang/module/ResolvedModule.java	Tue Feb 11 13:41:48 2020 +0530
@@ -79,7 +79,7 @@
      * @return The module descriptor
      */
     ModuleDescriptor descriptor() {
-        return reference().descriptor();
+        return mref.descriptor();
     }
 
     /**
@@ -93,7 +93,7 @@
      * @return The module name
      */
     public String name() {
-        return reference().descriptor().name();
+        return mref.descriptor().name();
     }
 
     /**
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Tue Feb 11 13:41:48 2020 +0530
@@ -904,6 +904,20 @@
         @Override public V replace(K key, V value) { throw uoe(); }
         @Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
         @Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
+
+        /**
+         * @implNote {@code null} values are disallowed in these immutable maps,
+         * so we can improve upon the default implementation since a
+         * {@code null} return from {@code get(key)} always means the default
+         * value should be returned.
+         */
+        @Override
+        public V getOrDefault(Object key, V defaultValue) {
+            V v;
+            return ((v = get(key)) != null)
+                    ? v
+                    : defaultValue;
+        }
     }
 
     static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Tue Feb 11 13:41:48 2020 +0530
@@ -2064,7 +2064,7 @@
         Node prev = null;
         Node firstTail = null;
         Branch branch = null;
-        Node branchConn = null;
+        BranchConn branchConn = null;
 
         for (;;) {
             Node node = sequence(end);
@@ -2212,7 +2212,24 @@
                 break;
             }
 
-            node = closure(node);
+            if (node instanceof LineEnding) {
+                LineEnding le = (LineEnding)node;
+                node = closureOfLineEnding(le);
+
+                if (node != le) {
+                    // LineEnding was replaced with an anonymous group
+                    if (head == null)
+                        head = node;
+                    else
+                        tail.next = node;
+                    // Double return: Tail was returned in root
+                    tail = root;
+                    continue;
+                }
+            } else {
+                node = closure(node);
+            }
+
             /* save the top dot-greedy nodes (.*, .+) as well
             if (node instanceof GreedyCharProperty &&
                 ((GreedyCharProperty)node).cp instanceof Dot) {
@@ -3079,18 +3096,31 @@
         if (saveTCNCount < topClosureNodes.size())
             topClosureNodes.subList(saveTCNCount, topClosureNodes.size()).clear();
 
+        return groupWithClosure(node, head, tail, capturingGroup);
+    }
+
+    /**
+     * Transforms a Group with quantifiers into some special constructs
+     * (such as Branch or Loop/GroupCurly), if necessary.
+     *
+     * This method is applied either to actual groups or to the Unicode
+     * linebreak (aka \\R) represented as an anonymous group.
+     */
+    private Node groupWithClosure(Node node, Node head, Node tail,
+                                  boolean capturingGroup)
+    {
         if (node instanceof Ques) {
             Ques ques = (Ques) node;
             if (ques.type == Qtype.POSSESSIVE) {
                 root = node;
                 return node;
             }
-            tail.next = new BranchConn();
-            tail = tail.next;
+            BranchConn branchConn = new BranchConn();
+            tail = tail.next = branchConn;
             if (ques.type == Qtype.GREEDY) {
-                head = new Branch(head, null, tail);
+                head = new Branch(head, null, branchConn);
             } else { // Reluctant quantifier
-                head = new Branch(null, head, tail);
+                head = new Branch(null, head, branchConn);
             }
             root = tail;
             return head;
@@ -3268,6 +3298,31 @@
     }
 
     /**
+     * Processing repetition of a Unicode linebreak \\R.
+     */
+    private Node closureOfLineEnding(LineEnding le) {
+        int ch = peek();
+        if (ch != '?' && ch != '*' && ch != '+' && ch != '{') {
+            return le;
+        }
+
+        // Replace the LineEnding with an anonymous group
+        // (?:\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029])
+        Node grHead = createGroup(true);
+        Node grTail = root;
+        BranchConn branchConn = new BranchConn();
+        branchConn.next = grTail;
+        Node slice = new Slice(new int[] {0x0D, 0x0A});
+        slice.next = branchConn;
+        Node chClass = newCharProperty(x -> x == 0x0A || x == 0x0B ||
+                x == 0x0C || x == 0x0D || x == 0x85 || x == 0x2028 ||
+                x == 0x2029);
+        chClass.next = branchConn;
+        grHead.next = new Branch(slice, chClass, branchConn);
+        return groupWithClosure(closure(grHead), grHead, grTail, false);
+    }
+
+    /**
      * Processes repetition. If the next character peeked is a quantifier
      * then new nodes must be appended to handle the repetition.
      * Prev could be a single or a group, so it could be a chain of nodes.
@@ -4723,8 +4778,8 @@
     static final class Branch extends Node {
         Node[] atoms = new Node[2];
         int size = 2;
-        Node conn;
-        Branch(Node first, Node second, Node branchConn) {
+        BranchConn conn;
+        Branch(Node first, Node second, BranchConn branchConn) {
             conn = branchConn;
             atoms[0] = first;
             atoms[1] = second;
@@ -4732,9 +4787,10 @@
 
         void add(Node node) {
             if (size >= atoms.length) {
-                Node[] tmp = new Node[atoms.length*2];
-                System.arraycopy(atoms, 0, tmp, 0, atoms.length);
-                atoms = tmp;
+                int len = ArraysSupport.newLength(size,
+                        1,    /* minimum growth */
+                        size  /* preferred growth */);
+                atoms = Arrays.copyOf(atoms, len);
             }
             atoms[size++] = node;
         }
--- a/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,8 @@
 import java.lang.module.Configuration;
 import java.lang.module.ModuleFinder;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
+import java.util.function.Function;
 
 import jdk.internal.misc.VM;
 
@@ -39,26 +39,26 @@
 final class ArchivedModuleGraph {
     private static ArchivedModuleGraph archivedModuleGraph;
 
-    private final String mainModule;
     private final boolean hasSplitPackages;
     private final boolean hasIncubatorModules;
     private final ModuleFinder finder;
     private final Configuration configuration;
+    private final Function<String, ClassLoader> classLoaderFunction;
     private final Map<String, Set<String>> concealedPackagesToOpen;
     private final Map<String, Set<String>> exportedPackagesToOpen;
 
-    private ArchivedModuleGraph(String mainModule,
-                                boolean hasSplitPackages,
-                                boolean hasIncubatorModules,
-                                ModuleFinder finder,
-                                Configuration configuration,
-                                Map<String, Set<String>> concealedPackagesToOpen,
-                                Map<String, Set<String>> exportedPackagesToOpen) {
-        this.mainModule = mainModule;
+    public ArchivedModuleGraph(boolean hasSplitPackages,
+                               boolean hasIncubatorModules,
+                               ModuleFinder finder,
+                               Configuration configuration,
+                               Function<String, ClassLoader> classLoaderFunction,
+                               Map<String, Set<String>> concealedPackagesToOpen,
+                               Map<String, Set<String>> exportedPackagesToOpen) {
         this.hasSplitPackages = hasSplitPackages;
         this.hasIncubatorModules = hasIncubatorModules;
         this.finder = finder;
         this.configuration = configuration;
+        this.classLoaderFunction = classLoaderFunction;
         this.concealedPackagesToOpen = concealedPackagesToOpen;
         this.exportedPackagesToOpen = exportedPackagesToOpen;
     }
@@ -71,6 +71,10 @@
         return configuration;
     }
 
+    Function<String, ClassLoader> classLoaderFunction() {
+        return classLoaderFunction;
+    }
+
     Map<String, Set<String>> concealedPackagesToOpen() {
         return concealedPackagesToOpen;
     }
@@ -92,7 +96,8 @@
      */
     static ArchivedModuleGraph get(String mainModule) {
         ArchivedModuleGraph graph = archivedModuleGraph;
-        if (graph != null && Objects.equals(mainModule, graph.mainModule)) {
+        // We only allow the unnamed module (default) case for now
+        if (mainModule == null) {
             return graph;
         } else {
             return null;
@@ -102,23 +107,8 @@
     /**
      * Archive the module graph for the given initial module.
      */
-    static void archive(String mainModule,
-                        boolean hasSplitPackages,
-                        boolean hasIncubatorModules,
-                        ModuleFinder finder,
-                        Configuration configuration,
-                        Map<String, Set<String>> concealedPackagesToOpen,
-                        Map<String, Set<String>> exportedPackagesToOpen) {
-        if (mainModule != null) {
-            throw new UnsupportedOperationException();
-        }
-        archivedModuleGraph = new ArchivedModuleGraph(mainModule,
-                                                      hasSplitPackages,
-                                                      hasIncubatorModules,
-                                                      finder,
-                                                      configuration,
-                                                      concealedPackagesToOpen,
-                                                      exportedPackagesToOpen);
+    static void archive(ArchivedModuleGraph graph) {
+        archivedModuleGraph = graph;
     }
 
     static {
--- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Tue Feb 11 13:41:48 2020 +0530
@@ -370,7 +370,12 @@
         // loader.
 
         // mapping of modules to class loaders
-        Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
+        Function<String, ClassLoader> clf;
+        if (archivedModuleGraph != null) {
+            clf = archivedModuleGraph.classLoaderFunction();
+        } else {
+            clf = ModuleLoaderMap.mappingFunction(cf);
+        }
 
         // check that all modules to be mapped to the boot loader will be
         // loaded from the runtime image
@@ -440,13 +445,14 @@
         // Module graph can be archived at CDS dump time. Only allow the
         // unnamed module case for now.
         if (canArchive && (mainModule == null)) {
-            ArchivedModuleGraph.archive(mainModule,
-                                        hasSplitPackages,
-                                        hasIncubatorModules,
-                                        systemModuleFinder,
-                                        cf,
-                                        concealedPackagesToOpen,
-                                        exportedPackagesToOpen);
+            ArchivedModuleGraph.archive(
+                    new ArchivedModuleGraph(hasSplitPackages,
+                                            hasIncubatorModules,
+                                            systemModuleFinder,
+                                            cf,
+                                            clf,
+                                            concealedPackagesToOpen,
+                                            exportedPackagesToOpen));
         }
 
         // total time to initialize
@@ -737,7 +743,6 @@
                         Modules.addExports(m, pn, other);
                     }
                 }
-
             }
         }
     }
--- a/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,14 +28,12 @@
 import java.lang.module.Configuration;
 import java.lang.module.ResolvedModule;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
 
 import jdk.internal.loader.ClassLoaders;
 
-
 /**
  * Supports the mapping of modules to class loaders. The set of modules mapped
  * to the boot and platform class loaders is generated at build time from
@@ -46,16 +44,55 @@
     /**
      * Maps the system modules to the built-in class loaders.
      */
-    public static final class Mapper implements Function<String, ClassLoader> {
-        private final Map<String, ClassLoader> map;
+    private static final class Mapper implements Function<String, ClassLoader> {
 
-        Mapper(Map<String, ClassLoader> map) {
-            this.map = map; // defensive copy not needed
+        private static final ClassLoader PLATFORM_CLASSLOADER =
+                ClassLoaders.platformClassLoader();
+        private static final ClassLoader APP_CLASSLOADER =
+                ClassLoaders.appClassLoader();
+
+        private static final Integer PLATFORM_LOADER_INDEX = 1;
+        private static final Integer APP_LOADER_INDEX      = 2;
+
+        /**
+         * Map from module to a class loader index. The index is resolved to the
+         * actual class loader in {@code apply}.
+         */
+        private final Map<String, Integer> map;
+
+        /**
+         * Creates a Mapper to map module names in the given Configuration to
+         * built-in classloaders.
+         *
+         * As a proxy for the actual classloader, we store an easily archiveable
+         * index value in the internal map. The index is stored as a boxed value
+         * so that we can cheaply do identity comparisons during bootstrap.
+         */
+        Mapper(Configuration cf) {
+            var map = new HashMap<String, Integer>();
+            for (ResolvedModule resolvedModule : cf.modules()) {
+                String mn = resolvedModule.name();
+                if (!Modules.bootModules.contains(mn)) {
+                    if (Modules.platformModules.contains(mn)) {
+                        map.put(mn, PLATFORM_LOADER_INDEX);
+                    } else {
+                        map.put(mn, APP_LOADER_INDEX);
+                    }
+                }
+            }
+            this.map = map;
         }
 
         @Override
         public ClassLoader apply(String name) {
-            return map.get(name);
+            Integer loader = map.get(name);
+            if (loader == APP_LOADER_INDEX) {
+                return APP_CLASSLOADER;
+            } else if (loader == PLATFORM_LOADER_INDEX) {
+                return PLATFORM_CLASSLOADER;
+            } else { // BOOT_LOADER_INDEX
+                return null;
+            }
         }
     }
 
@@ -63,50 +100,40 @@
      * Returns the names of the modules defined to the boot loader.
      */
     public static Set<String> bootModules() {
-        // The list of boot modules generated at build time.
-        String[] BOOT_MODULES = new String[] { "@@BOOT_MODULE_NAMES@@" };
-        Set<String> bootModules = new HashSet<>(BOOT_MODULES.length);
-        for (String mn : BOOT_MODULES) {
-            bootModules.add(mn);
-        }
-        return bootModules;
+        return Modules.bootModules;
     }
 
     /**
      * Returns the names of the modules defined to the platform loader.
      */
     public static Set<String> platformModules() {
-        // The list of platform modules generated at build time.
-        String[] PLATFORM_MODULES = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
-        Set<String> platformModules = new HashSet<>(PLATFORM_MODULES.length);
-        for (String mn : PLATFORM_MODULES) {
-            platformModules.add(mn);
-        }
-        return platformModules;
+        return Modules.platformModules;
+    }
+
+    private static class Modules {
+        // list of boot modules is generated at build time.
+        private static final Set<String> bootModules =
+                Set.of(new String[] { "@@BOOT_MODULE_NAMES@@" });
+
+        // list of platform modules is generated at build time.
+        private static final Set<String> platformModules =
+                Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" });
     }
 
     /**
-     * Returns the function to map modules in the given configuration to the
+     * Returns a function to map modules in the given configuration to the
      * built-in class loaders.
      */
     static Function<String, ClassLoader> mappingFunction(Configuration cf) {
-        Set<String> bootModules = bootModules();
-        Set<String> platformModules = platformModules();
+        return new Mapper(cf);
+    }
 
-        ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
-        ClassLoader appClassLoader = ClassLoaders.appClassLoader();
-
-        Map<String, ClassLoader> map = new HashMap<>();
-        for (ResolvedModule resolvedModule : cf.modules()) {
-            String mn = resolvedModule.name();
-            if (!bootModules.contains(mn)) {
-                if (platformModules.contains(mn)) {
-                    map.put(mn, platformClassLoader);
-                } else {
-                    map.put(mn, appClassLoader);
-                }
-            }
-        }
-        return new Mapper(map);
+    /**
+     * When defining modules for a configuration, we only allow defining modules
+     * to the boot or platform classloader if the ClassLoader mapping function
+     * originate from here.
+     */
+    public static boolean isBuiltinMapper(Function<String, ClassLoader> clf) {
+        return clf instanceof Mapper;
     }
 }
--- a/src/java.base/share/classes/module-info.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/classes/module-info.java	Tue Feb 11 13:41:48 2020 +0530
@@ -162,7 +162,8 @@
         jdk.jlink;
     exports jdk.internal.loader to
         java.instrument,
-        java.logging;
+        java.logging,
+        java.naming;
     exports jdk.internal.jmod to
         jdk.compiler,
         jdk.jlink;
--- a/src/java.base/share/legal/cldr.md	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/share/legal/cldr.md	Tue Feb 11 13:41:48 2020 +0530
@@ -1,4 +1,4 @@
-## Unicode Common Local Data Repository (CLDR) v35.1
+## Unicode Common Local Data Repository (CLDR) v36
 
 ### CLDR License
 
--- a/src/java.base/unix/native/libjava/childproc.c	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/unix/native/libjava/childproc.c	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 
 #include "childproc.h"
 
+const char * const *parentPathv;
 
 ssize_t
 restartableWrite(int fd, const void *buf, size_t count)
--- a/src/java.base/unix/native/libjava/childproc.h	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.base/unix/native/libjava/childproc.h	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,7 +126,7 @@
  * The cached and split version of the JDK's effective PATH.
  * (We don't support putenv("PATH=...") in native code)
  */
-const char * const *parentPathv;
+extern const char * const *parentPathv;
 
 ssize_t restartableWrite(int fd, const void *buf, size_t count);
 int restartableDup2(int fd_from, int fd_to);
--- a/src/java.naming/share/classes/javax/naming/spi/NamingManager.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.naming/share/classes/javax/naming/spi/NamingManager.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,13 +26,15 @@
 package javax.naming.spi;
 
 import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.*;
 
-
 import javax.naming.*;
 import com.sun.naming.internal.VersionHelper;
 import com.sun.naming.internal.ResourceManager;
 import com.sun.naming.internal.FactoryEnumeration;
+import jdk.internal.loader.ClassLoaderValue;
 
 /**
  * This class contains methods for creating context objects
@@ -79,6 +81,9 @@
      */
     private static ObjectFactoryBuilder object_factory_builder = null;
 
+    private static final ClassLoaderValue<InitialContextFactory> FACTORIES_CACHE =
+            new ClassLoaderValue<>();
+
     /**
      * The ObjectFactoryBuilder determines the policy used when
      * trying to load object factories.
@@ -672,6 +677,7 @@
      */
     public static Context getInitialContext(Hashtable<?,?> env)
         throws NamingException {
+        ClassLoader loader;
         InitialContextFactory factory = null;
 
         InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
@@ -689,39 +695,22 @@
                 throw ne;
             }
 
-            ServiceLoader<InitialContextFactory> loader =
-                    ServiceLoader.load(InitialContextFactory.class);
-
-            Iterator<InitialContextFactory> iterator = loader.iterator();
-            try {
-                while (iterator.hasNext()) {
-                    InitialContextFactory f = iterator.next();
-                    if (f.getClass().getName().equals(className)) {
-                        factory = f;
-                        break;
-                    }
-                }
-            } catch (ServiceConfigurationError e) {
-                NoInitialContextException ne =
-                        new NoInitialContextException(
-                                "Cannot load initial context factory "
-                                        + "'" + className + "'");
-                ne.setRootCause(e);
-                throw ne;
+            if (System.getSecurityManager() == null) {
+                loader = Thread.currentThread().getContextClassLoader();
+                if (loader == null) loader = ClassLoader.getSystemClassLoader();
+            } else {
+                PrivilegedAction<ClassLoader> pa = () -> {
+                    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+                    return (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
+                };
+                loader = AccessController.doPrivileged(pa);
             }
 
-            if (factory == null) {
-                try {
-                    @SuppressWarnings("deprecation")
-                    Object o = helper.loadClass(className).newInstance();
-                    factory = (InitialContextFactory) o;
-                } catch (Exception e) {
-                    NoInitialContextException ne =
-                            new NoInitialContextException(
-                                    "Cannot instantiate class: " + className);
-                    ne.setRootCause(e);
-                    throw ne;
-                }
+            var key = FACTORIES_CACHE.sub(className);
+            try {
+                factory = key.computeIfAbsent(loader, (ld, ky) -> getFactory(ky.key()));
+            } catch (FactoryInitializationError e) {
+                throw e.getCause();
             }
         } else {
             factory = builder.createInitialContextFactory(env);
@@ -730,6 +719,43 @@
         return factory.getInitialContext(env);
     }
 
+    private static InitialContextFactory getFactory(String className) {
+        InitialContextFactory factory;
+        try {
+            ServiceLoader<InitialContextFactory> loader =
+                    ServiceLoader.load(InitialContextFactory.class);
+
+            factory = loader
+                    .stream()
+                    .filter(p -> p.type().getName().equals(className))
+                    .findFirst()
+                    .map(ServiceLoader.Provider::get)
+                    .orElse(null);
+        } catch (ServiceConfigurationError e) {
+            NoInitialContextException ne =
+                    new NoInitialContextException(
+                            "Cannot load initial context factory "
+                                    + "'" + className + "'");
+            ne.setRootCause(e);
+            throw new FactoryInitializationError(ne);
+        }
+
+        if (factory == null) {
+            try {
+                @SuppressWarnings("deprecation")
+                Object o = helper.loadClass(className).newInstance();
+                factory = (InitialContextFactory) o;
+            } catch (Exception e) {
+                NoInitialContextException ne =
+                        new NoInitialContextException(
+                                "Cannot instantiate class: " + className);
+                ne.setRootCause(e);
+                throw new FactoryInitializationError(ne);
+            }
+        }
+        return factory;
+    }
+
 
     /**
      * Sets the InitialContextFactory builder to be builder.
@@ -921,4 +947,18 @@
 
         return (answer != null) ? answer : obj;
     }
+
+    private static class FactoryInitializationError extends Error {
+        @java.io.Serial
+        static final long serialVersionUID = -5805552256848841560L;
+
+        private FactoryInitializationError(NoInitialContextException cause) {
+            super(cause);
+        }
+
+        @Override
+        public NoInitialContextException getCause() {
+            return (NoInitialContextException) super.getCause();
+        }
+    }
 }
--- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java	Tue Feb 11 13:41:48 2020 +0530
@@ -305,9 +305,7 @@
      * Checks if the keytab file exists. Implementation of this method
      * should make sure that the result matches the latest status of the
      * keytab file.
-     * <p>
-     * The caller can use the result to determine if it should fallback to
-     * another mechanism to read the keys.
+     *
      * @return true if the keytab file exists; false otherwise.
      * @throws SecurityException if a security manager exists and the read
      * access to the keytab file is not permitted
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,8 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 
 import jdk.vm.ci.common.JVMCIError;
@@ -61,6 +63,7 @@
 
     private static final HotSpotResolvedJavaField[] NO_FIELDS = new HotSpotResolvedJavaField[0];
     private static final int METHOD_CACHE_ARRAY_CAPACITY = 8;
+    private static final SortByOffset fieldSortingMethod = new SortByOffset();
 
     /**
      * The Java class this type represents.
@@ -708,6 +711,12 @@
         }
     }
 
+    static class SortByOffset implements Comparator<ResolvedJavaField> {
+        public int compare(ResolvedJavaField a, ResolvedJavaField b) {
+            return a.getOffset() - b.getOffset();
+        }
+    }
+
     @Override
     public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
         if (instanceFields == null) {
@@ -727,8 +736,17 @@
                 // This class does not have any instance fields of its own.
                 return NO_FIELDS;
             } else if (superClassFieldCount != 0) {
+                // Fields of the current class can be interleaved with fields of its super-classes
+                // but the array of fields to be returned must be sorted by increasing offset
+                // This code populates the array, then applies the sorting function
                 HotSpotResolvedJavaField[] result = new HotSpotResolvedJavaField[instanceFields.length - superClassFieldCount];
-                System.arraycopy(instanceFields, superClassFieldCount, result, 0, result.length);
+                int i = 0;
+                for (HotSpotResolvedJavaField f : instanceFields) {
+                    if (f.getDeclaringClass() == this) {
+                        result[i++] = f;
+                    }
+                }
+                Arrays.sort(result, fieldSortingMethod);
                 return result;
             } else {
                 // The super classes of this class do not have any instance fields.
@@ -781,23 +799,19 @@
             System.arraycopy(prepend, 0, result, 0, prependLength);
         }
 
+        // Fields of the current class can be interleaved with fields of its super-classes
+        // but the array of fields to be returned must be sorted by increasing offset
+        // This code populates the array, then applies the sorting function
         int resultIndex = prependLength;
         for (int i = 0; i < index; ++i) {
             FieldInfo field = new FieldInfo(i);
             if (field.isStatic() == retrieveStaticFields) {
                 int offset = field.getOffset();
                 HotSpotResolvedJavaField resolvedJavaField = createField(field.getType(), offset, field.getAccessFlags(), i);
-
-                // Make sure the result is sorted by offset.
-                int j;
-                for (j = resultIndex - 1; j >= prependLength && result[j].getOffset() > offset; j--) {
-                    result[j + 1] = result[j];
-                }
-                result[j + 1] = resolvedJavaField;
-                resultIndex++;
+                result[resultIndex++] = resolvedJavaField;
             }
         }
-
+        Arrays.sort(result, fieldSortingMethod);
         return result;
     }
 
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -101,7 +101,7 @@
     final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*");
     final int instanceKlassFieldsOffset = getFieldOffset("InstanceKlass::_fields", Integer.class, "Array<u2>*");
     final int instanceKlassAnnotationsOffset = getFieldOffset("InstanceKlass::_annotations", Integer.class, "Annotations*");
-    final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags", Integer.class, "u2");
+    final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags", Integer.class, "u4");
     final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int");
     final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int");
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java	Tue Feb 11 13:41:48 2020 +0530
@@ -89,7 +89,7 @@
         this.typeElement = typeElement;
         this.utils = configuration.utils;
         this.contents = configuration.contents;
-        this.resources = configuration.resources;
+        this.resources = configuration.docResources;
         this.links = writer.links;
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -202,7 +202,7 @@
             Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprLabel);
             if (!deprs.isEmpty()) {
 
-                List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0));
                 if (!commentTags.isEmpty()) {
                     addInlineDeprecatedComment(annotationType, deprs.get(0), div);
                 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -495,7 +495,7 @@
             if (!deprs.isEmpty()) {
                 CommentHelper ch = utils.getCommentHelper(typeElement);
                 DocTree dt = deprs.get(0);
-                List<? extends DocTree> commentTags = ch.getBody(configuration, dt);
+                List<? extends DocTree> commentTags = ch.getBody(dt);
                 if (!commentTags.isEmpty()) {
                     addInlineDeprecatedComment(typeElement, deprs.get(0), div);
                 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -182,7 +182,7 @@
      * resources used to look up resource keys, and other details.
      */
     Contents(HtmlConfiguration configuration) {
-        this.resources = configuration.getResources();
+        this.resources = configuration.getDocResources();
 
         allClassesLabel = getNonBreakContent("doclet.All_Classes");
         allImplementedInterfacesLabel = getContent("doclet.All_Implemented_Interfaces");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Tue Feb 11 13:41:48 2020 +0530
@@ -78,7 +78,7 @@
      */
     public static final String HTML_DEFAULT_CHARSET = "utf-8";
 
-    public final Resources resources;
+    public final Resources docResources;
 
     /**
      * First file to appear in the right-hand frame in the generated
@@ -133,17 +133,31 @@
      */
     public HtmlConfiguration(Doclet doclet, Locale locale, Reporter reporter) {
         super(doclet, locale, reporter);
-        resources = new Resources(locale,
+
+        // Use the default locale for console messages.
+        Resources msgResources = new Resources(Locale.getDefault(),
                 BaseConfiguration.sharedResourceBundleName,
                 "jdk.javadoc.internal.doclets.formats.html.resources.standard");
 
-        messages = new Messages(this);
+        // Use the provided locale for generated docs
+        // Ideally, the doc resources would be in different resource files than the
+        // message resources, so that we do not have different copies of the same resources.
+        if (locale.equals(Locale.getDefault())) {
+            docResources = msgResources;
+        } else {
+            docResources = new Resources(locale,
+                    BaseConfiguration.sharedResourceBundleName,
+                    "jdk.javadoc.internal.doclets.formats.html.resources.standard");
+        }
+
+        messages = new Messages(this, msgResources);
         contents = new Contents(this);
         options = new HtmlOptions(this);
 
         String v;
         try {
-            ResourceBundle rb = ResourceBundle.getBundle(versionBundleName, getLocale());
+            // the version bundle is not localized
+            ResourceBundle rb = ResourceBundle.getBundle(versionBundleName, Locale.getDefault());
             try {
                 v = rb.getString("release");
             } catch (MissingResourceException e) {
@@ -166,10 +180,15 @@
     }
 
     @Override
-    public Resources getResources() {
-        return resources;
+    public Resources getDocResources() {
+        return docResources;
     }
 
+    /**
+     * Returns a utility object providing commonly used fragments of content.
+     *
+     * @return a utility object providing commonly used fragments of content
+     */
     public Contents getContents() {
         return contents;
     }
@@ -335,12 +354,7 @@
             Character unicode = (tagLabel.length() == 0)
                     ? '*'
                     : Character.toUpperCase(tagLabel.charAt(0));
-            List<SearchIndexItem> list = tagSearchIndexMap.get(unicode);
-            if (list == null) {
-                list = new ArrayList<>();
-                tagSearchIndexMap.put(unicode, list);
-            }
-            list.add(sii);
+            tagSearchIndexMap.computeIfAbsent(unicode, k -> new ArrayList<>()).add(sii);
         }
         tagSearchIndexKeys = tagSearchIndexMap.keySet();
     }
@@ -359,7 +373,7 @@
             if (options.charset() == null) {
                 options.setCharset(options.docEncoding());
             } else if (!options.charset().equals(options.docEncoding())) {
-                reporter.print(ERROR, resources.getText("doclet.Option_conflict", "-charset", "-docencoding"));
+                messages.error("doclet.Option_conflict", "-charset", "-docencoding");
                 return false;
             }
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Tue Feb 11 13:41:48 2020 +0530
@@ -213,7 +213,7 @@
         this.options = configuration.getOptions();
         this.contents = configuration.contents;
         this.messages = configuration.messages;
-        this.resources = configuration.resources;
+        this.resources = configuration.docResources;
         this.links = new Links(path);
         this.utils = configuration.utils;
         this.path = path;
@@ -1038,14 +1038,14 @@
             return new RawHtml(seetext);
         }
         boolean isLinkPlain = kind == LINK_PLAIN;
-        Content label = plainOrCode(isLinkPlain, new RawHtml(ch.getLabel(configuration, see)));
+        Content label = plainOrCode(isLinkPlain, new RawHtml(ch.getLabel(see)));
 
         //The text from the @see tag.  We will output this text when a label is not specified.
         Content text = plainOrCode(kind == LINK_PLAIN, new RawHtml(seetext));
 
-        TypeElement refClass = ch.getReferencedClass(configuration, see);
-        String refClassName =  ch.getReferencedClassName(configuration, see);
-        Element refMem =       ch.getReferencedMember(configuration, see);
+        TypeElement refClass = ch.getReferencedClass(see);
+        String refClassName =  ch.getReferencedClassName(see);
+        Element refMem =       ch.getReferencedMember(see);
         String refMemName =    ch.getReferencedMemberName(see);
 
         if (refMemName == null && refMem != null) {
@@ -1053,7 +1053,7 @@
         }
         if (refClass == null) {
             //@see is not referencing an included class
-            PackageElement refPackage = ch.getReferencedPackage(configuration, see);
+            PackageElement refPackage = ch.getReferencedPackage(see);
             if (refPackage != null && utils.isIncluded(refPackage)) {
                 //@see is referencing an included package
                 if (label.isEmpty())
@@ -1169,7 +1169,7 @@
      */
     public void addInlineComment(Element element, DocTree tag, Content htmltree) {
         CommentHelper ch = utils.getCommentHelper(element);
-        List<? extends DocTree> description = ch.getDescription(configuration, tag);
+        List<? extends DocTree> description = ch.getDescription(tag);
         addCommentTags(element, tag, description, false, false, false, htmltree);
     }
 
@@ -1194,7 +1194,7 @@
      */
     public void addInlineDeprecatedComment(Element e, DocTree tag, Content htmltree) {
         CommentHelper ch = utils.getCommentHelper(e);
-        addCommentTags(e, ch.getBody(configuration, tag), true, false, false, htmltree);
+        addCommentTags(e, ch.getBody(tag), true, false, false, htmltree);
     }
 
     /**
@@ -1220,8 +1220,8 @@
 
     public void addSummaryDeprecatedComment(Element element, DocTree tag, Content htmltree) {
         CommentHelper ch = utils.getCommentHelper(element);
-        List<? extends DocTree> body = ch.getBody(configuration, tag);
-        addCommentTags(element, ch.getFirstSentenceTrees(configuration, body), true, true, true, htmltree);
+        List<? extends DocTree> body = ch.getBody(tag);
+        addCommentTags(element, ch.getFirstSentenceTrees(body), true, true, true, htmltree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java	Tue Feb 11 13:41:48 2020 +0530
@@ -33,15 +33,12 @@
 import java.util.TreeSet;
 
 import com.sun.tools.doclint.DocLint;
-import jdk.javadoc.doclet.Reporter;
 import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
+import jdk.javadoc.internal.doclets.toolkit.Messages;
 import jdk.javadoc.internal.doclets.toolkit.Resources;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
 
-import static javax.tools.Diagnostic.Kind.ERROR;
-import static javax.tools.Diagnostic.Kind.WARNING;
-
 /**
  * Storage for all options supported by the
  * {@link jdk.javadoc.doclet.StandardDoclet standard doclet},
@@ -199,8 +196,8 @@
 
     @Override
     public Set<? extends Option> getSupportedOptions() {
-        Resources resources = config.getResources();
-        Reporter reporter = config.getReporter();
+        Messages messages = config.getMessages();
+        Resources resources = messages.getResources();
 
         List<Option> options = List.of(
                 new Option(resources, "--add-stylesheet", 1) {
@@ -255,13 +252,11 @@
                     @Override
                     public boolean process(String opt,  List<String> args) {
                         if (noHelp) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-helpfile", "-nohelp"));
+                            messages.error("doclet.Option_conflict", "-helpfile", "-nohelp");
                             return false;
                         }
                         if (!helpFile.isEmpty()) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_reuse",
-                                    "-helpfile"));
+                            messages.error("doclet.Option_reuse", "-helpfile");
                             return false;
                         }
                         helpFile = args.get(0);
@@ -281,8 +276,7 @@
                     public boolean process(String opt, List<String> args) {
                         noHelp = true;
                         if (!helpFile.isEmpty()) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-nohelp", "-helpfile"));
+                            messages.error("doclet.Option_conflict", "-nohelp", "-helpfile");
                             return false;
                         }
                         return true;
@@ -302,8 +296,7 @@
                     public boolean process(String opt,  List<String> args) {
                         createIndex = false;
                         if (splitIndex) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-noindex", "-splitindex"));
+                            messages.error("doclet.Option_conflict", "-noindex", "-splitindex");
                             return false;
                         }
                         return true;
@@ -323,8 +316,7 @@
                     public boolean process(String opt,  List<String> args) {
                         noOverview = true;
                         if (overviewPath != null) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-nooverview", "-overview"));
+                            messages.error("doclet.Option_conflict", "-nooverview", "-overview");
                             return false;
                         }
                         return true;
@@ -344,8 +336,7 @@
                     public boolean process(String opt,  List<String> args) {
                         overviewPath = args.get(0);
                         if (noOverview) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-overview", "-nooverview"));
+                            messages.error("doclet.Option_conflict", "-overview", "-nooverview");
                             return false;
                         }
                         return true;
@@ -365,8 +356,7 @@
                     public boolean process(String opt, List<String> args) {
                         splitIndex = true;
                         if (!createIndex) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_conflict",
-                                    "-splitindex", "-noindex"));
+                            messages.error("doclet.Option_conflict", "-splitindex", "-noindex");
                             return false;
                         }
                         return true;
@@ -418,11 +408,11 @@
                     public boolean process(String opt,  List<String> args) {
                         String dopt = opt.replace("-Xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX);
                         if (dopt.contains("/")) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_doclint_no_qualifiers"));
+                            messages.error("doclet.Option_doclint_no_qualifiers");
                             return false;
                         }
                         if (!DocLint.isValidOption(dopt)) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_doclint_invalid_arg"));
+                            messages.error("doclet.Option_doclint_invalid_arg");
                             return false;
                         }
                         doclintOpts.add(dopt);
@@ -435,7 +425,7 @@
                     public boolean process(String opt,  List<String> args) {
                         String dopt = opt.replace("-Xdoclint/package:", DocLint.XCHECK_PACKAGE);
                         if (!DocLint.isValidOption(dopt)) {
-                            reporter.print(ERROR, resources.getText("doclet.Option_doclint_package_invalid_arg"));
+                            messages.error("doclet.Option_doclint_package_invalid_arg");
                             return false;
                         }
                         doclintOpts.add(dopt);
@@ -450,7 +440,7 @@
                         try {
                             new URL(docrootParent);
                         } catch (MalformedURLException e) {
-                            reporter.print(ERROR, resources.getText("doclet.MalformedURL", docrootParent));
+                            messages.error("doclet.MalformedURL", docrootParent);
                             return false;
                         }
                         return true;
@@ -460,7 +450,7 @@
                 new XOption(resources, "--no-frames") {
                     @Override
                     public boolean process(String opt, List<String> args) {
-                        reporter.print(WARNING, resources.getText("doclet.NoFrames_specified"));
+                        messages.warning("doclet.NoFrames_specified");
                         return true;
                     }
                 }
@@ -477,14 +467,13 @@
             return false;
         }
 
-        Resources resources = config.getResources();
-        Reporter reporter = config.getReporter();
+        Messages messages = config.getMessages();
 
         // check if helpfile exists
         if (!helpFile.isEmpty()) {
             DocFile help = DocFile.createFileForInput(config, helpFile);
             if (!help.exists()) {
-                reporter.print(ERROR, resources.getText("doclet.File_not_found", helpFile));
+                messages.error("doclet.File_not_found", helpFile);
                 return false;
             }
         }
@@ -492,7 +481,7 @@
         if (!stylesheetFile.isEmpty()) {
             DocFile stylesheet = DocFile.createFileForInput(config, stylesheetFile);
             if (!stylesheet.exists()) {
-                reporter.print(ERROR, resources.getText("doclet.File_not_found", stylesheetFile));
+                messages.error("doclet.File_not_found", stylesheetFile);
                 return false;
             }
         }
@@ -500,7 +489,7 @@
         for (String ssheet : additionalStylesheets) {
             DocFile ssfile = DocFile.createFileForInput(config, ssheet);
             if (!ssfile.exists()) {
-                reporter.print(ERROR, resources.getText("doclet.File_not_found", ssheet));
+                messages.error("doclet.File_not_found", ssheet);
                 return false;
             }
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java	Tue Feb 11 13:41:48 2020 +0530
@@ -180,7 +180,7 @@
     @Override
     public void addMemberDescription(VariableElement field, DocTree serialFieldTag, Content contentTree) {
         CommentHelper ch = utils.getCommentHelper(field);
-        List<? extends DocTree> description = ch.getDescription(configuration, serialFieldTag);
+        List<? extends DocTree> description = ch.getDescription(serialFieldTag);
         if (!description.isEmpty()) {
             Content serialFieldContent = new RawHtml(ch.getText(description));
             Content div = HtmlTree.DIV(HtmlStyle.block, serialFieldContent);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -234,7 +234,7 @@
      * @return the tool tip for the appropriate class.
      */
     private String getClassToolTip(TypeElement typeElement, boolean isTypeLink) {
-        Resources resources = m_writer.configuration.getResources();
+        Resources resources = m_writer.configuration.getDocResources();
         if (isTypeLink) {
             return resources.getText("doclet.Href_Type_Param_Title",
                     utils.getSimpleName(typeElement));
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -375,16 +375,16 @@
         });
         // Generate the map of all services listed using @provides, and the description.
         (utils.getBlockTags(mdle, DocTree.Kind.PROVIDES)).forEach((tree) -> {
-            TypeElement t = ch.getServiceType(configuration, tree);
+            TypeElement t = ch.getServiceType(tree);
             if (t != null) {
-                providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false, true));
+                providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(tree), false, true));
             }
         });
         // Generate the map of all services listed using @uses, and the description.
         (utils.getBlockTags(mdle, DocTree.Kind.USES)).forEach((tree) -> {
-            TypeElement t = ch.getServiceType(configuration, tree);
+            TypeElement t = ch.getServiceType(tree);
             if (t != null) {
-                usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false, true));
+                usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(tree), false, true));
             }
         });
     }
@@ -827,7 +827,7 @@
             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(mdle));
             deprDiv.add(deprPhrase);
             if (!deprs.isEmpty()) {
-                List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0));
                 if (!commentTags.isEmpty()) {
                     addInlineDeprecatedComment(mdle, deprs.get(0), deprDiv);
                 }
@@ -892,7 +892,7 @@
             deprDiv.add(deprPhrase);
             if (!deprs.isEmpty()) {
                 CommentHelper ch = utils.getCommentHelper(pkg);
-                List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0));
                 if (!commentTags.isEmpty()) {
                     addInlineDeprecatedComment(pkg, deprs.get(0), deprDiv);
                 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -153,7 +153,7 @@
             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement));
             deprDiv.add(deprPhrase);
             if (!deprs.isEmpty()) {
-                List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0));
                 if (!commentTags.isEmpty()) {
                     addInlineDeprecatedComment(packageElement, deprs.get(0), deprDiv);
                 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Tue Feb 11 13:41:48 2020 +0530
@@ -97,7 +97,7 @@
         this.configuration  = configuration;
         this.options = configuration.getOptions();
         this.messages = configuration.getMessages();
-        this.resources = configuration.resources;
+        this.resources = configuration.docResources;
         this.utils = configuration.utils;
         this.docEnv = rd;
         this.outputdir = outputdir;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Tue Feb 11 13:41:48 2020 +0530
@@ -88,7 +88,7 @@
         configuration = htmlWriter.configuration;
         options = configuration.getOptions();
         utils = configuration.utils;
-        resources = configuration.getResources();
+        resources = configuration.getDocResources();
     }
 
     @Override
@@ -139,7 +139,7 @@
                 result.add(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
                         htmlWriter.getDeprecatedPhrase(element)));
                 if (!deprs.isEmpty()) {
-                    List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                    List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0));
                     if (!commentTags.isEmpty()) {
                         result.add(commentTagsToOutput(null, element, commentTags, false));
                     }
@@ -150,7 +150,7 @@
                 result.add(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
                         htmlWriter.getDeprecatedPhrase(element)));
                 if (!deprs.isEmpty()) {
-                    List<? extends DocTree> bodyTags = ch.getBody(configuration, deprs.get(0));
+                    List<? extends DocTree> bodyTags = ch.getBody(deprs.get(0));
                     Content body = commentTagsToOutput(null, element, bodyTags, false);
                     if (!body.isEmpty())
                         result.add(HtmlTree.DIV(HtmlStyle.deprecationComment, body));
@@ -191,7 +191,7 @@
         Content nameTree = new StringContent(paramName);
         body.add(HtmlTree.CODE(defineID ? HtmlTree.SPAN_ID("param-" + paramName, nameTree) : nameTree));
         body.add(" - ");
-        List<? extends DocTree> description = ch.getDescription(configuration, paramTag);
+        List<? extends DocTree> description = ch.getDescription(paramTag);
         body.add(htmlWriter.commentTagsToContent(paramTag, element, description, false, inSummary));
         return HtmlTree.DD(body);
     }
@@ -215,7 +215,7 @@
         result.add(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.returnLabel,
                 new StringContent(resources.getText("doclet.Returns")))));
         result.add(HtmlTree.DD(htmlWriter.commentTagsToContent(
-                returnTag, element, ch.getDescription(configuration, returnTag), false, inSummary)));
+                returnTag, element, ch.getDescription(returnTag), false, inSummary)));
         return result;
     }
 
@@ -279,7 +279,7 @@
             if (many) {
                 body.add(", ");
             }
-            List<? extends DocTree> bodyTags = ch.getBody(configuration, simpleTag);
+            List<? extends DocTree> bodyTags = ch.getBody(simpleTag);
             body.add(htmlWriter.commentTagsToContent(simpleTag, element, bodyTags, false, inSummary));
             many = true;
         }
@@ -292,7 +292,7 @@
         ContentBuilder result = new ContentBuilder();
         result.add(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
         CommentHelper ch = utils.getCommentHelper(element);
-        List<? extends DocTree> description = ch.getDescription(configuration, simpleTag);
+        List<? extends DocTree> description = ch.getDescription(simpleTag);
         Content body = htmlWriter.commentTagsToContent(simpleTag, element, description, false, inSummary);
         result.add(HtmlTree.DD(body));
         return result;
@@ -317,7 +317,7 @@
     public Content throwsTagOutput(Element element, DocTree throwsTag, TypeMirror substituteType) {
         ContentBuilder body = new ContentBuilder();
         CommentHelper ch = utils.getCommentHelper(element);
-        Element exception = ch.getException(configuration, throwsTag);
+        Element exception = ch.getException(throwsTag);
         Content excName;
         if (substituteType != null) {
            excName = htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
@@ -333,7 +333,7 @@
             excName = htmlWriter.getLink(link);
         }
         body.add(HtmlTree.CODE(excName));
-        List<? extends DocTree> description = ch.getDescription(configuration, throwsTag);
+        List<? extends DocTree> description = ch.getDescription(throwsTag);
         Content desc = htmlWriter.commentTagsToContent(throwsTag, element, description, false, inSummary);
         if (desc != null && !desc.isEmpty()) {
             body.add(" - ");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Navigation.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Navigation.java	Tue Feb 11 13:41:48 2020 +0530
@@ -141,7 +141,7 @@
         this.path = path;
         this.pathToRoot = path.parent().invert();
         this.links = new Links(path);
-        this.rowListTitle = configuration.getResources().getText("doclet.Navigation");
+        this.rowListTitle = configuration.getDocResources().getText("doclet.Navigation");
         this.searchLabel = contents.getContent("doclet.search");
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -151,7 +151,7 @@
 
     private void reportInternalError(Throwable t) {
         if (getClass().equals(StandardDoclet.class) || getClass().equals(HtmlDoclet.class)) {
-            System.err.println(configuration.getResources().getText("doclet.internal.report.bug"));
+            System.err.println(configuration.getDocResources().getText("doclet.internal.report.bug"));
         }
         dumpStack(true, t);
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java	Tue Feb 11 13:41:48 2020 +0530
@@ -60,8 +60,6 @@
 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberCache;
 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable;
 
-import static javax.tools.Diagnostic.Kind.*;
-
 /**
  * Configure the output based on the options. Doclets should sub-class
  * BaseConfiguration, to configure and add their own options. This class contains
@@ -154,7 +152,7 @@
 
     public abstract Messages getMessages();
 
-    public abstract Resources getResources();
+    public abstract Resources getDocResources();
 
     /**
      * Returns a string identifying the version of the doclet.
@@ -334,9 +332,7 @@
         }
 
         // add entries for modules which may not have exported packages
-        modules.forEach((ModuleElement mdle) -> {
-            modulePackages.computeIfAbsent(mdle, m -> Collections.emptySet());
-        });
+        modules.forEach(mdle -> modulePackages.computeIfAbsent(mdle, m -> Collections.emptySet()));
 
         modules.addAll(modulePackages.keySet());
         showModules = !modules.isEmpty();
@@ -396,18 +392,18 @@
     private void initDestDirectory() throws DocletException {
         String destDirName = getOptions().destDirName();
         if (!destDirName.isEmpty()) {
-            Resources resources = getResources();
+            Messages messages = getMessages();
             DocFile destDir = DocFile.createFileForDirectory(this, destDirName);
             if (!destDir.exists()) {
                 //Create the output directory (in case it doesn't exist yet)
-                reporter.print(NOTE, resources.getText("doclet.dest_dir_create", destDirName));
+                messages.notice("doclet.dest_dir_create", destDirName);
                 destDir.mkdirs();
             } else if (!destDir.isDirectory()) {
-                throw new SimpleDocletException(resources.getText(
+                throw new SimpleDocletException(messages.getResources().getText(
                         "doclet.destination_directory_not_directory_0",
                         destDir.getPath()));
             } else if (!destDir.canWrite()) {
-                throw new SimpleDocletException(resources.getText(
+                throw new SimpleDocletException(messages.getResources().getText(
                         "doclet.destination_directory_not_writable_0",
                         destDir.getPath()));
             }
@@ -689,12 +685,12 @@
      */
     public boolean isJavaFXMode() {
         TypeElement observable = utils.elementUtils.getTypeElement("javafx.beans.Observable");
-        if (observable != null) {
-            ModuleElement javafxModule = utils.elementUtils.getModuleOf(observable);
-            if (javafxModule == null || javafxModule.isUnnamed() || javafxModule.getQualifiedName().contentEquals("javafx.base")) {
-                return true;
-            }
+        if (observable == null) {
+            return false;
         }
-        return false;
+        ModuleElement javafxModule = utils.elementUtils.getModuleOf(observable);
+        return javafxModule == null
+                || javafxModule.isUnnamed()
+                || javafxModule.getQualifiedName().contentEquals("javafx.base");
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java	Tue Feb 11 13:41:48 2020 +0530
@@ -271,7 +271,7 @@
     }
 
     public Set<? extends Option> getSupportedOptions() {
-        Resources resources = config.getResources();
+        Resources resources = config.getDocResources();
         Messages messages = config.getMessages();
         Reporter reporter = config.getReporter();
 
@@ -572,7 +572,7 @@
             osw = new OutputStreamWriter(ost, docencoding);
         } catch (UnsupportedEncodingException exc) {
             config.reporter.print(ERROR,
-                    config.getResources().getText("doclet.Encoding_not_supported", docencoding));
+                    config.getDocResources().getText("doclet.Encoding_not_supported", docencoding));
             return false;
         } finally {
             try {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
     protected CommentUtils(BaseConfiguration configuration) {
         this.configuration = configuration;
         utils = configuration.utils;
-        resources = configuration.getResources();
+        resources = configuration.getDocResources();
         trees = configuration.docEnv.getDocTrees();
         treeFactory = trees.getDocTreeFactory();
         elementUtils = configuration.docEnv.getElementUtils();
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Messages.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Messages.java	Tue Feb 11 13:41:48 2020 +0530
@@ -51,16 +51,26 @@
      * Creates a {@code Messages} object to provide standardized access to
      * the doclet's diagnostic reporting mechanisms.
      *
-     * @param configuration the doclet's configuration, used to access
-     *  the doclet's resources, reporter, and additional methods and state
-     *  used to filter out messages, if any, which should be suppressed.
+     * @param configuration the doclet's configuration, used to access the doclet's
+     *                      reporter, and additional methods and state used to
+     *                      filter out messages, if any, which should be suppressed.
+     * @param resources     resources for console messages and exceptions
      */
-    public Messages(BaseConfiguration configuration) {
+    public Messages(BaseConfiguration configuration, Resources resources) {
         this.configuration = configuration;
-        resources = configuration.getResources();
+        this.resources = resources;
         reporter = configuration.getReporter();
     }
 
+    /**
+     * Returns the resources being used when generating messages.
+     *
+     * @return the resources
+     */
+    public Resources getResources() {
+        return resources;
+    }
+
     // ***** Errors *****
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Resources.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Resources.java	Tue Feb 11 13:41:48 2020 +0530
@@ -63,7 +63,6 @@
      *                         specific to a particular format
      */
     public Resources(Locale locale, String commonBundleName, String docletBundleName) {
-
         this.commonBundle = ResourceBundle.getBundle(commonBundleName, locale);
         this.docletBundle = ResourceBundle.getBundle(docletBundleName, locale);
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java	Tue Feb 11 13:41:48 2020 +0530
@@ -100,7 +100,7 @@
         this.options = configuration.getOptions();
         this.builderFactory = configuration.getBuilderFactory();
         this.messages = configuration.getMessages();
-        this.resources = configuration.getResources();
+        this.resources = configuration.getDocResources();
         this.utils = configuration.utils;
         this.containingPackagesSeen = c.containingPackagesSeen;
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Tue Feb 11 13:41:48 2020 +0530
@@ -482,7 +482,7 @@
             if (tag.getName() == null || tag.getType() == null)  // ignore malformed @serialField tags
                 continue;
             Content fieldsContentTree = fieldWriter.getFieldsContentHeader(tag.equals(tags.last()));
-            TypeElement te = ch.getReferencedClass(configuration, tag);
+            TypeElement te = ch.getReferencedClass(tag);
             String fieldType = ch.getReferencedMemberName(tag);
             if (te != null && utils.isPrimitive(te.asType())) {
                 fieldType = utils.getTypeName(te.asType(), false);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/BasePropertyTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/BasePropertyTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -49,23 +49,13 @@
     }
 
     /**
-     * This method returns the text to be put in the resulting javadoc before
-     * the property name.
+     * Returns the text to be included in the documentation before the property name.
      *
-     * @param tagletWriter the taglet writer for output
-     * @return the string to be put in the resulting javadoc.
+     * @param tagletWriter the taglet-writer used by the doclet
+     * @return the text to be included in the documentation before the property name
      */
     abstract String getText(TagletWriter tagletWriter);
 
-    /**
-     * Given the <code>Tag</code> representation of this custom
-     * tag, return its string representation, which is output
-     * to the generated page.
-     * @param element
-     * @param tag the <code>Tag</code> representation of this custom tag.
-     * @param tagletWriter the taglet writer for output.
-     * @return the TagletOutput representation of this <code>Tag</code>.
-     */
     @Override
     public Content getTagletOutput(Element element, DocTree tag, TagletWriter tagletWriter) {
         return tagletWriter.propertyTagOutput(element, tag, getText(tagletWriter));
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/BaseTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/BaseTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -188,11 +188,21 @@
                 : tree.getKind() == tagKind;
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec This implementation throws {@link UnsupportedTagletOperationException}.
+     */
     @Override
     public Content getTagletOutput(Element element, DocTree tag, TagletWriter writer) {
         throw new UnsupportedTagletOperationException("Method not supported in taglet " + getName() + ".");
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec This implementation throws {@link UnsupportedTagletOperationException}
+     */
     @Override
     public Content getTagletOutput(Element holder, TagletWriter writer) {
         throw new UnsupportedTagletOperationException("Method not supported in taglet " + getName() + ".");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,7 +126,7 @@
             if (rankMap.containsKey(paramName) && rankMap.get(paramName).equals((input.tagId))) {
                 output.holder = input.element;
                 output.holderTag = tag;
-                output.inlineTags = ch.getBody(utils.configuration, tag);
+                output.inlineTags = ch.getBody(tag);
                 return;
             }
         }
@@ -305,7 +305,7 @@
                 case RECORD_COMPONENT: key = "doclet.RecordComponents" ; break;
                 default: throw new IllegalArgumentException(kind.toString());
             }
-            String header = writer.configuration().getResources().getText(key);
+            String header = writer.configuration().getDocResources().getText(key);
             result.add(writer.getParamHeader(header));
         }
         result.add(writer.paramTagOutput(e, paramTag, name));
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/PropertyGetterTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/PropertyGetterTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,6 @@
 
 package jdk.javadoc.internal.doclets.toolkit.taglets;
 
-import java.util.List;
-
-import javax.lang.model.element.Element;
-
-import com.sun.source.doctree.DocTree;
-import jdk.javadoc.internal.doclets.toolkit.Content;
-
 /**
  * A taglet that adds the initial line of documentation to the JavaFX
  * property getters.
@@ -52,6 +45,6 @@
 
     @Override
     String getText(TagletWriter tagletWriter) {
-        return tagletWriter.configuration().getResources().getText("doclet.PropertyGetter");
+        return tagletWriter.configuration().getDocResources().getText("doclet.PropertyGetter");
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/PropertySetterTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/PropertySetterTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,6 @@
 
     @Override
     String getText(TagletWriter tagletWriter) {
-        return tagletWriter.configuration().getResources().getText("doclet.PropertySetter");
+        return tagletWriter.configuration().getDocResources().getText("doclet.PropertySetter");
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -64,8 +64,8 @@
             output.holder = input.element;
             output.holderTag = tags.get(0);
             output.inlineTags = input.isFirstSentence
-                    ? ch.getFirstSentenceTrees(input.utils.configuration, output.holderTag)
-                    : ch.getDescription(input.utils.configuration, output.holderTag);
+                    ? ch.getFirstSentenceTrees(output.holderTag)
+                    : ch.getDescription(output.holderTag);
         }
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -60,7 +60,7 @@
             output.holder = input.element;
             output.holderTag = tags.get(0);
             output.inlineTags = input.isFirstSentence
-                    ? ch.getFirstSentenceTrees(input.utils.configuration, output.holderTag)
+                    ? ch.getFirstSentenceTrees(output.holderTag)
                     : ch.getReference(output.holderTag);
         }
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SimpleTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SimpleTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -173,8 +173,8 @@
             output.holderTag = tags.get(0);
             CommentHelper ch = input.utils.getCommentHelper(output.holder);
             output.inlineTags = input.isFirstSentence
-                    ? ch.getFirstSentenceTrees(input.utils.configuration, output.holderTag)
-                    : ch.getTags(input.utils.configuration, output.holderTag);
+                    ? ch.getFirstSentenceTrees(output.holderTag)
+                    : ch.getTags(output.holderTag);
         }
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/Taglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/Taglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -135,29 +135,28 @@
     String getName();
 
     /**
-     * Given the <code>Tag</code> representation of this custom
-     * tag, return its Content representation, which is output
-     * to the generated page.
-     * @param holder the element holding the tag
-     * @param tag the <code>Tag</code> representation of this custom tag.
-     * @param writer a {@link TagletWriter} Taglet writer.
-     * @throws UnsupportedOperationException thrown when the method is not supported by the taglet.
-     * @return the Content representation of this <code>Tag</code>.
+     * Returns the content to be included in the generated output for an
+     * instance of a tag handled by this taglet.
+     *
+     * @param element the element for the enclosing doc comment
+     * @param tag     the tag
+     * @param writer  the taglet-writer used in this doclet
+     * @return the output for this tag
+     * @throws UnsupportedTagletOperationException thrown when the method is not supported by the taglet
      */
-    Content getTagletOutput(Element holder, DocTree tag, TagletWriter writer) throws
-            UnsupportedOperationException;
+    Content getTagletOutput(Element element, DocTree tag, TagletWriter writer) throws
+            UnsupportedTagletOperationException;
 
     /**
-     * Given an element object, check if it holds any tags of
-     * this type.  If it does, return the content representing the output.
-     * If it does not, return null.
-     * @param holder an element holding the custom tag.
-     * @param writer a {@link TagletWriter} Taglet writer.
-     * @throws UnsupportedTagletOperationException thrown when the method is not
-     *         supported by the taglet.
-     * @return the content representation of this <code>Tag</code>.
+     * Returns the content to be included in the generated output for all
+     * instances of tags handled by this taglet.
+     *
+     * @param element the element for the enclosing doc comment
+     * @param writer  the taglet-writer used in this doclet
+     * @return the output for this tag
+     * @throws UnsupportedTagletOperationException thrown when the method is not supported by the taglet
      */
-    Content getTagletOutput(Element holder, TagletWriter writer) throws
+    Content getTagletOutput(Element element, TagletWriter writer) throws
             UnsupportedTagletOperationException;
 
     class UnsupportedTagletOperationException extends UnsupportedOperationException {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Tue Feb 11 13:41:48 2020 +0530
@@ -199,7 +199,7 @@
         this.docEnv = configuration.docEnv;
         this.doclet = configuration.doclet;
         this.messages = configuration.getMessages();
-        this.resources = configuration.getResources();
+        this.resources = configuration.getDocResources();
         this.showTaglets = options.showTaglets();
         this.utils = configuration.utils;
         this.tagletPath = options.tagletPath();
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -72,26 +72,25 @@
         Element exception;
         CommentHelper ch = utils.getCommentHelper(input.element);
         if (input.tagId == null) {
-            exception = ch.getException(utils.configuration, input.docTreeInfo.docTree);
+            exception = ch.getException(input.docTreeInfo.docTree);
             input.tagId = exception == null
                     ? ch.getExceptionName(input.docTreeInfo.docTree).getSignature()
                     : utils.getFullyQualifiedName(exception);
         } else {
-            TypeElement element = input.utils.findClass(input.element, input.tagId);
-            exception = (element == null) ? null : element;
+            exception = input.utils.findClass(input.element, input.tagId);
         }
 
         for (DocTree dt : input.utils.getThrowsTrees(input.element)) {
-            Element texception = ch.getException(utils.configuration, dt);
-            if (texception != null && (input.tagId.equals(utils.getSimpleName(texception)) ||
-                 (input.tagId.equals(utils.getFullyQualifiedName(texception))))) {
+            Element exc = ch.getException(dt);
+            if (exc != null && (input.tagId.equals(utils.getSimpleName(exc)) ||
+                 (input.tagId.equals(utils.getFullyQualifiedName(exc))))) {
                 output.holder = input.element;
                 output.holderTag = dt;
-                output.inlineTags = ch.getBody(input.utils.configuration, output.holderTag);
+                output.inlineTags = ch.getBody(output.holderTag);
                 output.tagList.add(dt);
-            } else if (exception != null && texception != null &&
-                    utils.isTypeElement(texception) && utils.isTypeElement(exception) &&
-                    utils.isSubclassOf((TypeElement)texception, (TypeElement)exception)) {
+            } else if (exception != null && exc != null &&
+                    utils.isTypeElement(exc) && utils.isTypeElement(exception) &&
+                    utils.isSubclassOf((TypeElement)exc, (TypeElement)exception)) {
                 output.tagList.add(dt);
             }
         }
@@ -106,15 +105,15 @@
         Content result = writer.getOutputInstance();
         //Add links to the exceptions declared but not documented.
         for (TypeMirror declaredExceptionType : declaredExceptionTypes) {
-            TypeElement klass = utils.asTypeElement(declaredExceptionType);
-            if (klass != null &&
+            TypeElement te = utils.asTypeElement(declaredExceptionType);
+            if (te != null &&
                 !alreadyDocumented.contains(declaredExceptionType.toString()) &&
-                !alreadyDocumented.contains(utils.getFullyQualifiedName(klass, false))) {
+                !alreadyDocumented.contains(utils.getFullyQualifiedName(te, false))) {
                 if (alreadyDocumented.isEmpty()) {
                     result.add(writer.getThrowsHeader());
                 }
                 result.add(writer.throwsTagOutput(declaredExceptionType));
-                alreadyDocumented.add(utils.getSimpleName(klass));
+                alreadyDocumented.add(utils.getSimpleName(te));
             }
         }
         return result;
@@ -176,18 +175,17 @@
     }
 
     /**
-     * Given an array of <code>Tag</code>s representing this custom
-     * tag, return its string representation.
-     * @param throwTags the array of <code>ThrowsTag</code>s to convert.
-     * @param writer the TagletWriter that will write this tag.
-     * @param alreadyDocumented the set of exceptions that have already
-     *        been documented.
-     * @param allowDups True if we allow duplicate throws tags to be documented.
-     * @return the Content representation of this <code>Tag</code>.
+     * Returns the generated content for a collection of {@code @throws} tags.
+     *
+     * @param throwTags         the collection of tags to be converted
+     * @param writer            the taglet-writer used by the doclet
+     * @param alreadyDocumented the set of exceptions that have already been documented
+     * @param allowDuplicates   {@code true} if we allow duplicate tags to be documented
+     * @return the generated content for the tags
      */
     protected Content throwsTagsOutput(Map<List<? extends DocTree>, ExecutableElement> throwTags,
                                        TagletWriter writer, Set<String> alreadyDocumented,
-                                       Map<String,TypeMirror> typeSubstitutions, boolean allowDups) {
+                                       Map<String,TypeMirror> typeSubstitutions, boolean allowDuplicates) {
         Utils utils = writer.configuration().utils;
         Content result = writer.getOutputInstance();
         if (!throwTags.isEmpty()) {
@@ -195,10 +193,10 @@
                 CommentHelper ch = utils.getCommentHelper(entry.getValue());
                 Element e = entry.getValue();
                 for (DocTree dt : entry.getKey()) {
-                    Element te = ch.getException(utils.configuration, dt);
+                    Element te = ch.getException(dt);
                     String excName = ch.getExceptionName(dt).toString();
                     TypeMirror substituteType = typeSubstitutions.get(excName);
-                    if ((!allowDups) &&
+                    if ((!allowDuplicates) &&
                         (alreadyDocumented.contains(excName) ||
                         (te != null && alreadyDocumented.contains(utils.getFullyQualifiedName(te, false)))) ||
                         (substituteType != null && alreadyDocumented.contains(substituteType.toString()))) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ValueTaglet.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ValueTaglet.java	Tue Feb 11 13:41:48 2020 +0530
@@ -77,7 +77,7 @@
 
         Element e = signature == null
                 ? holder
-                : ch.getReferencedMember(config, tag);
+                : ch.getReferencedMember(tag);
 
         return (e != null && config.utils.isVariableElement(e))
                 ? (VariableElement) e
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java	Tue Feb 11 13:41:48 2020 +0530
@@ -28,11 +28,10 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.Name;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.TypeMirror;
@@ -84,18 +83,27 @@
  *  deletion without notice.</b>
  */
 public class CommentHelper {
+    private final BaseConfiguration configuration;
     public final TreePath path;
-    public final DocCommentTree dctree;
+    public final DocCommentTree dcTree;
     public final Element element;
     private Element overriddenElement;
 
     public static final String SPACER = " ";
 
-    public CommentHelper(BaseConfiguration configuration, Element element, TreePath path, DocCommentTree dctree) {
-        //this.configuration = configuration;
+    /**
+     * Creates a utility class to encapsulate the contextual information for a doc comment tree.
+     *
+     * @param configuration the configuration
+     * @param element       the element for which this is a doc comment
+     * @param path          the path for the element
+     * @param dcTree        the doc comment
+     */
+    public CommentHelper(BaseConfiguration configuration, Element element, TreePath path, DocCommentTree dcTree) {
+        this.configuration = configuration;
         this.element = element;
         this.path = path;
-        this.dctree = dctree;
+        this.dcTree = dcTree;
     }
 
     public void setOverrideElement(Element ove) {
@@ -144,17 +152,18 @@
         }
     }
 
-    Element getElement(BaseConfiguration c, ReferenceTree rtree) {
+    Element getElement(ReferenceTree rtree) {
+        Utils utils = configuration.utils;
         // likely a synthesized tree
         if (path == null) {
             // NOTE: this code path only supports module/package/type signatures
             //       and not member signatures. For more complete support,
             //       set a suitable path and avoid this branch.
-            TypeMirror symbol = c.utils.getSymbol(rtree.getSignature());
+            TypeMirror symbol = utils.getSymbol(rtree.getSignature());
             if (symbol == null) {
                 return null;
             }
-            return  c.docEnv.getTypeUtils().asElement(symbol);
+            return configuration.docEnv.getTypeUtils().asElement(symbol);
         }
         // case A: the element contains no comments associated and
         // the comments need to be copied from ancestor
@@ -162,37 +171,37 @@
         // as appropriate has to be copied over.
 
         // Case A.
-        if (dctree == null && overriddenElement != null) {
-            CommentHelper ovch = c.utils.getCommentHelper(overriddenElement);
-            return ovch.getElement(c, rtree);
+        if (dcTree == null && overriddenElement != null) {
+            CommentHelper ovch = utils.getCommentHelper(overriddenElement);
+            return ovch.getElement(rtree);
         }
-        if (dctree == null) {
+        if (dcTree == null) {
             return null;
         }
-        DocTreePath docTreePath = DocTreePath.getPath(path, dctree, rtree);
+        DocTreePath docTreePath = DocTreePath.getPath(path, dcTree, rtree);
         if (docTreePath == null) {
             // Case B.
             if (overriddenElement != null) {
-                CommentHelper ovch = c.utils.getCommentHelper(overriddenElement);
-                return ovch.getElement(c, rtree);
+                CommentHelper ovch = utils.getCommentHelper(overriddenElement);
+                return ovch.getElement(rtree);
             }
             return null;
         }
-        DocTrees doctrees = c.docEnv.getDocTrees();
+        DocTrees doctrees = configuration.docEnv.getDocTrees();
         return doctrees.getElement(docTreePath);
     }
 
-    public Element getException(BaseConfiguration c, DocTree dtree) {
+    public Element getException(DocTree dtree) {
         if (dtree.getKind() == THROWS || dtree.getKind() == EXCEPTION) {
             ThrowsTree tt = (ThrowsTree)dtree;
             ReferenceTree exceptionName = tt.getExceptionName();
-            return getElement(c, exceptionName);
+            return getElement(exceptionName);
         }
         return null;
     }
 
-    public List<? extends DocTree> getDescription(BaseConfiguration c, DocTree dtree) {
-        return getTags(c, dtree);
+    public List<? extends DocTree> getDescription(DocTree dtree) {
+        return getTags(dtree);
     }
 
     public String getText(List<? extends DocTree> list) {
@@ -224,16 +233,14 @@
                         quote = "\"";
                         break;
                     case SINGLE:
-                        quote = "\'";
+                        quote = "'";
                         break;
                     default:
                         quote = "";
                         break;
                 }
                 sb.append(quote);
-                node.getValue().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getValue().forEach(dt -> dt.accept(this, null));
                 sb.append(quote);
                 return null;
             }
@@ -259,9 +266,7 @@
                 }
 
                 node.getReference().accept(this, null);
-                node.getLabel().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getLabel().forEach(dt -> dt.accept(this, null) );
                 return null;
             }
 
@@ -285,17 +290,13 @@
 
             @Override
             public Void visitSee(SeeTree node, Void p) {
-                node.getReference().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getReference().forEach(dt -> dt.accept(this, null));
                 return null;
             }
 
             @Override
             public Void visitSerial(SerialTree node, Void p) {
-                node.getDescription().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getDescription().forEach(dt -> dt.accept(this, null));
                 return null;
             }
 
@@ -303,9 +304,7 @@
             public Void visitStartElement(StartElementTree node, Void p) {
                 sb.append("<");
                 sb.append(node.getName());
-                node.getAttributes().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getAttributes().forEach(dt -> dt.accept(this, null));
                 sb.append((node.isSelfClosing() ? "/>" : ">"));
                 return null;
             }
@@ -318,9 +317,7 @@
 
             @Override
             public Void visitUnknownBlockTag(UnknownBlockTagTree node, Void p) {
-                node.getContent().stream().forEach((dt) -> {
-                    dt.accept(this, null);
-                });
+                node.getContent().forEach(dt -> dt.accept(this, null));
                 return null;
             }
 
@@ -338,24 +335,22 @@
         return sb;
     }
 
-    public String getLabel(BaseConfiguration c, DocTree dtree) {
+    public String getLabel(DocTree dtree) {
         return new SimpleDocTreeVisitor<String, Void>() {
             @Override
             public String visitLink(LinkTree node, Void p) {
-                StringBuilder sb = new StringBuilder();
-                node.getLabel().stream().forEach((dt) -> {
-                    sb.append(getText(dt));
-                });
-                return sb.toString();
+                return node.getLabel().stream()
+                        .map(dt -> getText(dt))
+                        .collect(Collectors.joining());
             }
 
             @Override
             public String visitSee(SeeTree node, Void p) {
-                StringBuilder sb = new StringBuilder();
-                node.getReference().stream().filter((dt) -> (c.utils.isText(dt))).forEach((dt) -> {
-                    sb.append(((TextTree)dt).getBody());
-                });
-                return sb.toString();
+                Utils utils = configuration.utils;
+                return node.getReference().stream()
+                        .filter(utils::isText)
+                        .map(dt -> ((TextTree) dt).getBody())
+                        .collect(Collectors.joining());
             }
 
             @Override
@@ -365,22 +360,24 @@
         }.visit(dtree, null);
     }
 
-    public TypeElement getReferencedClass(BaseConfiguration c, DocTree dtree) {
-        Element e = getReferencedElement(c, dtree);
+    public TypeElement getReferencedClass(DocTree dtree) {
+        Utils utils = configuration.utils;
+        Element e = getReferencedElement(dtree);
         if (e == null) {
             return null;
-        } else if (c.utils.isTypeElement(e)) {
+        } else if (utils.isTypeElement(e)) {
             return (TypeElement) e;
-        } else if (!c.utils.isPackage(e)) {
-            return c.utils.getEnclosingTypeElement(e);
+        } else if (!utils.isPackage(e)) {
+            return utils.getEnclosingTypeElement(e);
         }
         return null;
     }
 
-    public String getReferencedClassName(BaseConfiguration c, DocTree dtree) {
-        Element e = getReferencedClass(c, dtree);
+    public String getReferencedClassName(DocTree dtree) {
+        Utils utils = configuration.utils;
+        Element e = getReferencedClass(dtree);
         if (e != null) {
-            return c.utils.isTypeElement(e) ? c.utils.getSimpleName(e) : null;
+            return utils.isTypeElement(e) ? utils.getSimpleName(e) : null;
         }
         String s = getReferencedSignature(dtree);
         if (s == null) {
@@ -390,12 +387,13 @@
         return (n == -1) ? s : s.substring(0, n);
     }
 
-    public Element getReferencedMember(BaseConfiguration c, DocTree dtree) {
-        Element e = getReferencedElement(c, dtree);
+    public Element getReferencedMember(DocTree dtree) {
+        Utils utils = configuration.utils;
+        Element e = getReferencedElement(dtree);
         if (e == null) {
             return null;
         }
-        return (c.utils.isExecutableElement(e) || c.utils.isVariableElement(e)) ? e : null;
+        return (utils.isExecutableElement(e) || utils.isVariableElement(e)) ? e : null;
     }
 
     public String getReferencedMemberName(DocTree dtree) {
@@ -407,33 +405,34 @@
         return (n == -1) ? null : s.substring(n + 1);
     }
 
-    public String getReferencedMemberName(BaseConfiguration c, Element e) {
+    public String getReferencedMemberName(Element e) {
         if (e == null) {
             return null;
         }
-        return c.utils.isExecutableElement(e)
-                ? c.utils.getSimpleName(e) + c.utils.makeSignature((ExecutableElement) e, true, true)
-                : c.utils.getSimpleName(e);
+        Utils utils = configuration.utils;
+        return utils.isExecutableElement(e)
+                ? utils.getSimpleName(e) + utils.makeSignature((ExecutableElement) e, true, true)
+                : utils.getSimpleName(e);
     }
 
-    public PackageElement getReferencedPackage(BaseConfiguration c, DocTree dtree) {
-        Element e = getReferencedElement(c, dtree);
+    public PackageElement getReferencedPackage(DocTree dtree) {
+        Element e = getReferencedElement(dtree);
         if (e != null) {
-            return c.utils.containingPackage(e);
+            Utils utils = configuration.utils;
+            return utils.containingPackage(e);
         }
         return null;
     }
 
-    public List<? extends DocTree> getFirstSentenceTrees(BaseConfiguration c, List<? extends DocTree> body) {
-        List<DocTree> firstSentence = c.docEnv.getDocTrees().getFirstSentence(body);
-        return firstSentence;
+    public List<? extends DocTree> getFirstSentenceTrees(List<? extends DocTree> body) {
+        return configuration.docEnv.getDocTrees().getFirstSentence(body);
     }
 
-    public List<? extends DocTree> getFirstSentenceTrees(BaseConfiguration c, DocTree dtree) {
-        return getFirstSentenceTrees(c, getBody(c, dtree));
+    public List<? extends DocTree> getFirstSentenceTrees(DocTree dtree) {
+        return getFirstSentenceTrees(getBody(dtree));
     }
 
-    private Element getReferencedElement(BaseConfiguration c, DocTree dtree) {
+    private Element getReferencedElement(DocTree dtree) {
         return new SimpleDocTreeVisitor<Element, Void>() {
             @Override
             public Element visitSee(SeeTree node, Void p) {
@@ -460,7 +459,7 @@
 
             @Override
             public Element visitReference(ReferenceTree node, Void p) {
-                return getElement(c, node);
+                return getElement(node);
             }
 
             @Override
@@ -480,10 +479,11 @@
         }.visit(dtree, null);
     }
 
-    public TypeElement getServiceType(BaseConfiguration c, DocTree dtree) {
-        Element e = getReferencedElement(c, dtree);
+    public TypeElement getServiceType(DocTree dtree) {
+        Element e = getReferencedElement(dtree);
         if (e != null) {
-            return c.utils.isTypeElement(e) ? (TypeElement) e : null;
+            Utils utils = configuration.utils;
+            return utils.isTypeElement(e) ? (TypeElement) e : null;
         }
         return null;
     }
@@ -546,11 +546,11 @@
             }
     }
 
-    public List<? extends DocTree> getTags(BaseConfiguration c, DocTree dtree) {
+    public List<? extends DocTree> getTags(DocTree dtree) {
         return new SimpleDocTreeVisitor<List<? extends DocTree>, Void>() {
             List<? extends DocTree> asList(String content) {
                 List<DocTree> out = new ArrayList<>();
-                out.add(c.cmtUtils.makeTextTree(content));
+                out.add(configuration.cmtUtils.makeTextTree(content));
                 return out;
             }
 
@@ -651,22 +651,22 @@
         }.visit(dtree, null);
     }
 
-    public List<? extends DocTree> getBody(BaseConfiguration c, DocTree dtree) {
-        return getTags(c, dtree);
+    public List<? extends DocTree> getBody(DocTree dtree) {
+        return getTags(dtree);
     }
 
     public ReferenceTree getType(DocTree dtree) {
         if (dtree.getKind() == SERIAL_FIELD) {
-            return ((SerialFieldTree)dtree).getType();
+            return ((SerialFieldTree) dtree).getType();
         } else {
             return null;
         }
     }
 
     public DocTreePath getDocTreePath(DocTree dtree) {
-        if (path == null || dctree == null || dtree == null)
+        if (path == null || dcTree == null || dtree == null)
             return null;
-        return DocTreePath.getPath(path, dctree, dtree);
+        return DocTreePath.getPath(path, dcTree, dtree);
     }
 
     public Element getOverriddenElement() {
@@ -680,7 +680,7 @@
      */
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("CommentHelper{" + "path=" + path + ", dctree=" + dctree);
+        StringBuilder sb = new StringBuilder("CommentHelper{" + "path=" + path + ", dcTree=" + dcTree);
         sb.append(", element=");
         sb.append(element.getEnclosingElement());
         sb.append("::");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,7 @@
 
     public Extern(BaseConfiguration configuration) {
         this.configuration = configuration;
-        this.resources = configuration.getResources();
+        this.resources = configuration.getDocResources();
         this.utils = configuration.utils;
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java	Tue Feb 11 13:41:48 2020 +0530
@@ -240,8 +240,8 @@
         Map<String, SortedSet<ModuleElement>> groupModuleMap = new HashMap<>();
         String defaultGroupName =
             (elementNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())?
-                configuration.getResources().getText("doclet.Modules") :
-                configuration.getResources().getText("doclet.Other_Modules");
+                configuration.getDocResources().getText("doclet.Modules") :
+                configuration.getDocResources().getText("doclet.Other_Modules");
         // if the user has not used the default group name, add it
         if (!groupList.contains(defaultGroupName)) {
             groupList.add(defaultGroupName);
@@ -282,8 +282,8 @@
         Map<String, SortedSet<PackageElement>> groupPackageMap = new HashMap<>();
         String defaultGroupName =
             (elementNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())?
-                configuration.getResources().getText("doclet.Packages") :
-                configuration.getResources().getText("doclet.Other_Packages");
+                configuration.getDocResources().getText("doclet.Packages") :
+                configuration.getDocResources().getText("doclet.Other_Packages");
         // if the user has not used the default group name, add it
         if (!groupList.contains(defaultGroupName)) {
             groupList.add(defaultGroupName);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/MetaKeywords.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/MetaKeywords.java	Tue Feb 11 13:41:48 2020 +0530
@@ -58,7 +58,7 @@
      */
     public MetaKeywords(BaseConfiguration configuration) {
         options = configuration.getOptions();
-        resources = configuration.getResources();
+        resources = configuration.getDocResources();
         utils = configuration.utils;
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java	Tue Feb 11 13:41:48 2020 +0530
@@ -86,7 +86,7 @@
                 fileManager.setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
             } catch (IOException e) {
                 // generic IOException from file manager, setting location, e.g. file not a directory
-                String message = configuration.getResources().getText("doclet.error.initializing.dest.dir", e);
+                String message = configuration.getDocResources().getText("doclet.error.initializing.dest.dir", e);
                 throw new SimpleDocletException(message, e);
             }
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Tue Feb 11 13:41:48 2020 +0530
@@ -32,9 +32,28 @@
 import java.text.Collator;
 import java.text.ParseException;
 import java.text.RuleBasedCollator;
-import java.util.*;
-import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -125,7 +144,7 @@
         configuration = c;
         options = configuration.getOptions();
         messages = configuration.getMessages();
-        resources = configuration.getResources();
+        resources = configuration.getDocResources();
         elementUtils = c.docEnv.getElementUtils();
         typeUtils = c.docEnv.getTypeUtils();
         docTrees = c.docEnv.getDocTrees();
@@ -937,7 +956,7 @@
      * @return
      */
     public TypeMirror getDeclaredType(Collection<TypeMirror> values,
-            TypeElement enclosing, TypeMirror target) {
+                                      TypeElement enclosing, TypeMirror target) {
         TypeElement targetElement = asTypeElement(target);
         List<? extends TypeParameterElement> targetTypeArgs = targetElement.getTypeParameters();
         if (targetTypeArgs.isEmpty()) {
@@ -2546,7 +2565,7 @@
         }.visit(e);
     }
 
-    EnumSet<ElementKind> nestedKinds = EnumSet.of(ANNOTATION_TYPE, CLASS, ENUM, INTERFACE);
+    Set<ElementKind> nestedKinds = EnumSet.of(ANNOTATION_TYPE, CLASS, ENUM, INTERFACE);
     void recursiveGetItems(Collection<Element> list, Element e, boolean filter, ElementKind... select) {
         list.addAll(getItems0(e, filter, select));
         List<Element> classes = getItems0(e, filter, nestedKinds);
@@ -2559,7 +2578,7 @@
     }
 
     private List<Element> getItems0(Element te, boolean filter, ElementKind... select) {
-        EnumSet<ElementKind> kinds = EnumSet.copyOf(Arrays.asList(select));
+        Set<ElementKind> kinds = EnumSet.copyOf(Arrays.asList(select));
         return getItems0(te, filter, kinds);
     }
 
@@ -3002,14 +3021,14 @@
         return  doctree.getKind() == match;
     }
 
-    private final WeakSoftHashMap wksMap = new WeakSoftHashMap(this);
+    private final CommentHelperCache commentHelperCache = new CommentHelperCache(this);
 
     public CommentHelper getCommentHelper(Element element) {
-        return wksMap.computeIfAbsent(element);
+        return commentHelperCache.computeIfAbsent(element);
     }
 
     public void removeCommentHelper(Element element) {
-        wksMap.remove(element);
+        commentHelperCache.remove(element);
     }
 
     public List<? extends DocTree> getBlockTags(Element element) {
@@ -3177,13 +3196,13 @@
     }
 
     public DocCommentTree getDocCommentTree(Element element) {
-        CommentHelper ch = wksMap.get(element);
+        CommentHelper ch = commentHelperCache.get(element);
         if (ch != null) {
-            return ch.dctree;
+            return ch.dcTree;
         }
         DocCommentTree dcTree = getDocCommentTree0(element);
         if (dcTree != null) {
-            wksMap.put(element, new CommentHelper(configuration, element, getTreePath(element), dcTree));
+            commentHelperCache.put(element, new CommentHelper(configuration, element, getTreePath(element), dcTree));
         }
         return dcTree;
     }
@@ -3297,106 +3316,48 @@
         return outer;
     }
 
-    static class WeakSoftHashMap implements Map<Element, CommentHelper> {
-
-        private final WeakHashMap<Element, SoftReference<CommentHelper>> wkMap;
+    /**
+     * A memory-sensitive cache for {@link CommentHelper} objects,
+     * which are expensive to compute.
+     */
+    private static class CommentHelperCache {
+
+        private final Map<Element, SoftReference<CommentHelper>> map;
         private final Utils utils;
-        public WeakSoftHashMap(Utils utils) {
-            wkMap = new WeakHashMap<>();
+
+        public CommentHelperCache(Utils utils) {
+            map = new HashMap<>();
             this.utils = utils;
         }
 
-        @Override
-        public boolean containsKey(Object key) {
-            return wkMap.containsKey(key);
-        }
-
-        @Override
-        public Collection<CommentHelper> values() {
-            Set<CommentHelper> out = new LinkedHashSet<>();
-            for (SoftReference<CommentHelper> v : wkMap.values()) {
-                out.add(v.get());
-            }
-            return out;
-        }
-
-        @Override
-        public boolean containsValue(Object value) {
-            return wkMap.containsValue(new SoftReference<>((CommentHelper)value));
-        }
-
-        @Override
-        public CommentHelper remove(Object key) {
-            SoftReference<CommentHelper> value = wkMap.remove(key);
+        public CommentHelper remove(Element key) {
+            SoftReference<CommentHelper> value = map.remove(key);
             return value == null ? null : value.get();
         }
 
-
-        @Override
         public CommentHelper put(Element key, CommentHelper value) {
-            SoftReference<CommentHelper> nvalue = wkMap.put(key, new SoftReference<>(value));
-            return nvalue == null ? null : nvalue.get();
+            SoftReference<CommentHelper> prev = map.put(key, new SoftReference<>(value));
+            return prev == null ? null : prev.get();
         }
 
-        @Override
         public CommentHelper get(Object key) {
-            SoftReference<CommentHelper> value = wkMap.get(key);
+            SoftReference<CommentHelper> value = map.get(key);
             return value == null ? null : value.get();
         }
 
-        @Override
-        public int size() {
-            return wkMap.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return wkMap.isEmpty();
-        }
-
-        @Override
-        public void clear() {
-            wkMap.clear();
-        }
-
         public CommentHelper computeIfAbsent(Element key) {
-            if (wkMap.containsKey(key)) {
-                SoftReference<CommentHelper> value = wkMap.get(key);
+            SoftReference<CommentHelper> refValue = map.get(key);
+            if (refValue != null) {
+                CommentHelper value = refValue.get();
                 if (value != null) {
-                    CommentHelper cvalue = value.get();
-                    if (cvalue != null) {
-                        return cvalue;
-                    }
+                    return value;
                 }
             }
             CommentHelper newValue = new CommentHelper(utils.configuration, key, utils.getTreePath(key),
                     utils.getDocCommentTree(key));
-            wkMap.put(key, new SoftReference<>(newValue));
+            map.put(key, new SoftReference<>(newValue));
             return newValue;
         }
-
-
-        @Override
-        public void putAll(Map<? extends Element, ? extends CommentHelper> map) {
-            for (Map.Entry<? extends Element, ? extends CommentHelper> entry : map.entrySet()) {
-                put(entry.getKey(), entry.getValue());
-            }
-        }
-
-        @Override
-        public Set<Element> keySet() {
-            return wkMap.keySet();
-        }
-
-        @Override
-        public Set<Entry<Element, CommentHelper>> entrySet() {
-            Set<Entry<Element, CommentHelper>> out = new LinkedHashSet<>();
-            for (Element e : wkMap.keySet()) {
-                SimpleEntry<Element, CommentHelper> n = new SimpleEntry<>(e, get(e));
-                out.add(n);
-            }
-            return out;
-        }
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Tue Feb 11 13:41:48 2020 +0530
@@ -399,14 +399,14 @@
             Throwable t = e.getCause();
             dumpStack(t == null ? e : t);
             return ERROR;
-        } catch (OptionException toe) {
-            if (toe.message != null)
-                messager.printError(toe.message);
+        } catch (OptionException oe) {
+            if (oe.message != null)
+                messager.printError(oe.message);
 
-            toe.m.run();
-            Throwable t = toe.getCause();
-            dumpStack(t == null ? toe : t);
-            return toe.result;
+            oe.m.run();
+            Throwable t = oe.getCause();
+            dumpStack(t == null ? oe : t);
+            return oe.result;
         } catch (ToolException exc) {
             if (exc.message != null) {
                 messager.printError(exc.message);
@@ -733,7 +733,7 @@
         }
 
         if (Doclet.class.isAssignableFrom(docletClass)) {
-            messager.setLocale(locale);
+            messager.setLocale(Locale.getDefault());  // use default locale for console messages
             try {
                 Object o = docletClass.getConstructor().newInstance();
                 doclet = (Doclet) o;
@@ -818,10 +818,6 @@
         messager.printErrorUsingKey(key, args);
     }
 
-    void warn(String key, Object... args)  {
-        messager.printWarningUsingKey(key, args);
-    }
-
     /**
      * Get the locale if specified on the command line
      * else return null and if locale option is not used
@@ -841,21 +837,4 @@
         }
     }
 
-    /**
-     * Search the locale for specified language, specified country and
-     * specified variant.
-     */
-    private Locale searchLocale(String language, String country,
-                                String variant) {
-        for (Locale loc : Locale.getAvailableLocales()) {
-            if (loc.getLanguage().equals(language) &&
-                (country == null || loc.getCountry().equals(country)) &&
-                (variant == null || loc.getVariant().equals(variant))) {
-                return loc;
-            }
-        }
-        return null;
-    }
-
-
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Tue Feb 11 13:41:48 2020 +0530
@@ -47,6 +47,21 @@
 
 /**
  * Plugin to generate java.lang.invoke classes.
+ *
+ * The plugin reads in a file generated by running any application with
+ * {@code -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true}. This is done
+ * automatically during build, see make/GenerateLinkOptData.gmk. See
+ * build/tools/classlist/HelloClasslist.java for the training application.
+ *
+ * HelloClasslist tries to reflect common use of java.lang.invoke during early
+ * startup and warmup in various applications. To ensure a good default
+ * trade-off between static footprint and startup the application should be
+ * relatively conservative.
+ *
+ * When using jlink to build a custom application runtime, generating a trace
+ * file using {@code -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true} and
+ * feeding that into jlink using {@code --generate-jli-classes=@trace_file} can
+ * help improve startup time.
  */
 public final class GenerateJLIClassesPlugin implements Plugin {
 
@@ -112,59 +127,6 @@
        return PluginsResourceBundle.getArgument(NAME);
     }
 
-    /**
-     * @return the default Species forms to generate.
-     *
-     * This list was derived from running a small startup benchmark.
-     * A better long-term solution is to define and run a set of quick
-     * generators and extracting this list as a step in the build process.
-     */
-    public static Set<String> defaultSpecies() {
-        return Set.of("LL", "L3", "L4", "L5", "L6", "L7", "L7I",
-                "L7II", "L7IIL", "L8", "L9", "L10", "L10I", "L10II", "L10IIL",
-                "L11", "L12", "L13", "LI", "D", "L3I", "LIL", "LLI", "LLIL",
-                "LILL", "I", "LLILL");
-    }
-
-    /**
-     * @return the default invoker forms to generate.
-     */
-    private static Set<String> defaultInvokers() {
-        return Set.of("LL_L", "LL_I", "LLLL_L", "LLLL_I", "LLIL_L", "LLIL_I",
-                "L6_L");
-    }
-
-    /**
-     * @return the default call site forms to generate (linkToTargetMethod).
-     */
-    private static Set<String> defaultCallSiteTypes() {
-        return Set.of("L5_L", "LIL3_L", "ILL_L");
-    }
-
-    /**
-     * @return the list of default DirectMethodHandle methods to generate.
-     */
-    private static Map<String, Set<String>> defaultDMHMethods() {
-        return Map.of(
-            DMH_INVOKE_INTERFACE, Set.of("LL_L", "L3_I", "L3_V"),
-            DMH_INVOKE_VIRTUAL, Set.of("LL_L", "LLI_I", "L3_V"),
-            DMH_INVOKE_SPECIAL, Set.of("LL_I", "LL_L", "LLF_L", "LLD_L",
-                "L3_I", "L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "L8_L",
-                "LLI_I", "LLI_L", "LLIL_I", "LLIL_L", "LLII_I", "LLII_L",
-                "L3I_L", "L3I_I", "L3ILL_L", "LLILI_I", "LLIIL_L", "LLIILL_L",
-                "LLIILL_I", "LLIIL_I", "LLILIL_I", "LLILILL_I", "LLILII_I",
-                "LLI3_I", "LLI3L_I", "LLI3LL_I", "LLI3_L", "LLI4_I"),
-            DMH_INVOKE_STATIC, Set.of("LII_I", "LIL_I", "LILIL_I", "LILII_I",
-                "L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L",
-                "LL_I", "LLILL_L", "LLIL3_L", "LL_V", "LL_L", "L3_I", "L3_L",
-                "L3_V", "L4_I", "L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "L9_L",
-                "L10_L", "L10I_L", "L10II_L", "L10IIL_L", "L11_L", "L12_L",
-                "L13_L", "L14_L", "L14I_L", "L14II_L"),
-            DMH_NEW_INVOKE_SPECIAL, Set.of("L_L", "LL_L"),
-            DMH_INVOKE_SPECIAL_IFC, Set.of("L5_I")
-        );
-    }
-
     private static int DMH_INVOKE_VIRTUAL_TYPE = 0;
     private static int DMH_INVOKE_INTERFACE_TYPE = 4;
 
@@ -201,19 +163,8 @@
     }
 
     public void initialize(ResourcePool in) {
-        // Start with the default configuration
-        defaultSpecies().stream().forEach(this::addSpeciesType);
-
-        defaultInvokers().stream().forEach(this::validateMethodType);
-
-        defaultCallSiteTypes().stream().forEach(this::addCallSiteType);
-
-        defaultDMHMethods().entrySet().stream().forEach(e -> {
-            e.getValue().stream().forEach(type -> addDMHMethodType(e.getKey(), type));
-        });
-
-        // Extend the default configuration with the contents in the supplied
-        // input file - if none was supplied we look for the default file
+        // Load configuration from the contents in the supplied input file
+        // - if none was supplied we look for the default file
         if (mainArgument == null || !mainArgument.startsWith("@")) {
             try (InputStream traceFile =
                     this.getClass().getResourceAsStream(DEFAULT_TRACE_FILE)) {
--- a/src/jdk.localedata/share/legal/cldr.md	Sat Feb 08 18:48:42 2020 -0800
+++ b/src/jdk.localedata/share/legal/cldr.md	Tue Feb 11 13:41:48 2020 +0530
@@ -1,4 +1,4 @@
-## Unicode Common Local Data Repository (CLDR) v35.1
+## Unicode Common Local Data Repository (CLDR) v36
 
 ### CLDR License
 
--- a/test/hotspot/jtreg/TEST.groups	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/TEST.groups	Tue Feb 11 13:41:48 2020 +0530
@@ -177,6 +177,7 @@
   applications/ctw/modules/jdk_compiler.java \
   applications/ctw/modules/jdk_internal_vm_compiler.java \
   applications/ctw/modules/jdk_localedata.java \
+  applications/ctw/modules/jdk_localedata_2.java \
   applications/ctw/modules/jdk_scripting_nashorn.java \
 
 tier1_gc = \
--- a/test/hotspot/jtreg/applications/ctw/modules/jdk_localedata.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_localedata.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @summary run CTW for all classes from jdk.localedata module
+ * @summary run CTW for some classes from jdk.localedata module
  *
  * @library /test/lib / /testlibrary/ctw/src
  * @modules java.base/jdk.internal.access
@@ -35,5 +35,5 @@
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run driver/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.localedata
+ * @run driver/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.localedata 0% 50%
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_localedata_2.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary run CTW for some classes from jdk.localedata module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.access
+ *          java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.localedata
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.localedata 50% 100%
+ */
--- a/test/hotspot/jtreg/containers/docker/TestJFREvents.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/containers/docker/TestJFREvents.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,11 +60,6 @@
         DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
 
         try {
-            // leave one CPU for system and tools, otherwise this test may be unstable
-            int maxNrOfAvailableCpus =  availableCPUs - 1;
-            for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {
-                testCPUInfo(i, i);
-            }
 
             long MB = 1024*1024;
             testMemory("200m", "" + 200*MB);
@@ -79,18 +74,26 @@
         }
     }
 
+    // This test case is currently not in use.
+    // Once new Container events are available, this test case can be used to test
+    // processor-related configuration such as active processor count (see JDK-8203359).
+    private static void cpuTestCase() throws Exception {
+            // leave one CPU for system and tools, otherwise this test may be unstable
+            int maxNrOfAvailableCpus =  availableCPUs - 1;
+            for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {
+                testCPUInfo("jdk.ContainerConfiguration", i, i);
+            }
+    }
 
-    private static void testCPUInfo(int valueToSet, int expectedValue) throws Exception {
+    private static void testCPUInfo(String eventName, int valueToSet, int expectedValue) throws Exception {
         Common.logNewTestCase("CPUInfo: --cpus = " + valueToSet);
+        String fieldName = "activeProcessorCount";
         DockerTestUtils.dockerRunJava(
                                       commonDockerOpts()
                                       .addDockerOpts("--cpus=" + valueToSet)
-                                      .addClassOptions("jdk.CPUInformation"))
-            .shouldHaveExitValue(0);
-        // The following assertion is currently disabled due to JFR reporting incorrect values.
-        // JFR reports values for the host system as opposed to values for the container.
-        // @ignore 8219999
-        // .shouldContain("cores = " + expectedValue");
+                                      .addClassOptions(eventName))
+            .shouldHaveExitValue(0)
+            .shouldContain(fieldName + " = " + expectedValue);
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8237837
+ * @summary  Shenandoah: assert(mem == __null) failed: only one safepoint
+ * @key gc
+ * @requires vm.flavor == "server"
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test -XX:CompileCommand=quiet BarrierInInfiniteLoop
+ *
+ */
+
+public class BarrierInInfiniteLoop {
+    private static Object field1 = new Object();
+    private static Object field2 = new Object();
+
+    public static void main(String[] args) {
+        test(false);
+    }
+
+    private static void test(boolean flag) {
+        if (flag) {
+            for (;;) {
+                field1 = field2;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/FoldIfAfterExpansion.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2020, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test 8238385
+ * @summary CTW: C2 (Shenandoah) compilation fails with "Range check dependent CastII node was not removed"
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @modules java.base/jdk.internal.misc:+open
+ *
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
+ *                   FoldIfAfterExpansion
+ *
+ */
+
+import jdk.internal.misc.Unsafe;
+
+public class FoldIfAfterExpansion {
+    private static int[] field1 = new int[100];
+    private static int[] field2 = new int[100];
+    private static int[] field3;
+    private static volatile int barrier;
+
+    static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 20_000; i++) {
+            test(true, 10, false, true);
+            test(false, 10, false, false);
+        }
+    }
+
+    private static Object test(boolean flag, int i, boolean flag2, boolean flag3) {
+        int[] array;
+        if (flag) {
+            barrier = 1;
+            array = field1;
+            final int length = array.length;
+            if (flag2) {
+                field3 = array;
+            }
+        } else {
+            barrier = 1;
+            array = field1;
+            final int length = array.length;
+            if (flag2) {
+                field3 = array;
+            }
+        }
+
+        array = field1;
+
+        if (flag3) {
+            if (i < 0 || i >= array.length) {
+                throw new RuntimeException();
+            }
+            long l = (long)i;
+            l = l * UNSAFE.ARRAY_INT_INDEX_SCALE + UNSAFE.ARRAY_INT_BASE_OFFSET;
+            UNSAFE.putInt(array, l, i);
+        } else {
+            if (i < 0 || i >= array.length) {
+                throw new RuntimeException();
+            }
+            long l = (long)i;
+            l = l * UNSAFE.ARRAY_INT_INDEX_SCALE + UNSAFE.ARRAY_INT_BASE_OFFSET;
+            UNSAFE.putInt(array, l, i);
+        }
+
+        return array;
+    }
+}
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,8 @@
         {"InitialRAMFraction",        "64"},
         {"TLABStats",                 "false"},
         {"AllowRedefinitionToAddDeleteMethods", "true"},
+        {"PrintVMQWaitTime",          "true"},
+        {"UseNewFieldLayout",         "true"},
 
         // deprecated alias flags (see also aliased_jvm_flags):
         {"DefaultMaxRAMFraction", "4"},
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/FieldLayout/FieldDensityTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8237767
+ * @summary Verify behaviour of field layout algorithm
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main/othervm FieldDensityTest
+ */
+
+/*
+ * @test
+ * @requires vm.bits == "64"
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main/othervm -XX:+UseCompressedOops -XX:+UseCompressedClassPointers FieldDensityTest
+ * @run main/othervm -XX:+UseCompressedOops -XX:-UseCompressedClassPointers FieldDensityTest
+ */
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Comparator;
+import jdk.internal.misc.Unsafe;
+
+import jdk.test.lib.Asserts;
+
+public class FieldDensityTest {
+
+    static int OOP_SIZE_IN_BYTES = 0;
+
+    static {
+        if (System.getProperty("sun.arch.data.model").equals("64")) {
+            if (System.getProperty("java.vm.compressedOopsMode") == null) {
+                OOP_SIZE_IN_BYTES = 8;
+            } else {
+                OOP_SIZE_IN_BYTES = 4;
+            }
+        } else {
+            OOP_SIZE_IN_BYTES = 4;
+        }
+    }
+
+    static class FieldInfo {
+        public Field field;
+        public long offset;
+
+        FieldInfo(Field field, long offset) {
+            this.field = field;
+            this.offset = offset;
+        }
+
+        static void checkFieldsContiguity(FieldInfo[] fieldInfo) {
+            Arrays.sort(fieldInfo, new SortByOffset());
+            for (int i = 0 ; i <  fieldInfo.length - 2; i++) {
+                int size = sizeInBytesFromType(fieldInfo[i].field.getType());
+                Asserts.assertEquals((int)(fieldInfo[i].offset + size), (int)fieldInfo[i+1].offset,
+                                     "Empty slot between fields, should not happen");
+            }
+        }
+    }
+
+    static int sizeInBytesFromType(Class type) {
+        if (!type.isPrimitive()) {
+            return OOP_SIZE_IN_BYTES;
+        }
+        switch(type.getTypeName()) {
+        case "boolean":
+        case "byte": return 1;
+        case "char":
+        case "short": return 2;
+        case "int":
+        case "float": return 4;
+        case "long":
+        case "double": return 8;
+        default:
+            throw new RuntimeException("Unrecognized signature");
+        }
+    }
+
+    static class SortByOffset implements Comparator<FieldInfo> {
+        public int compare(FieldInfo a, FieldInfo b)
+        {
+            return (int)(a.offset - b.offset);
+        }
+    }
+
+    static class E {
+        public byte b0;
+    }
+
+    static class F extends E {
+        public byte b1;
+    }
+
+    static class G extends F {
+        public byte b2;
+    }
+
+    static class H extends G {
+        public byte b3;
+    }
+
+    public static class A {
+        public int i;
+        public byte b;
+        public long l;
+        public Object o;
+    }
+
+    public static class B extends A {
+        public byte b0, b1, b2;
+    }
+
+    static void testFieldsContiguity(Class c) {
+        Unsafe unsafe = Unsafe.getUnsafe();
+        Field[] fields = c.getFields();
+        FieldInfo[] fieldsInfo = new FieldInfo[fields.length];
+        int i = 0;
+        for (Field f : fields) {
+            long offset = unsafe.objectFieldOffset(f);
+            fieldsInfo[i] = new FieldInfo(f, offset);
+            i++;
+        }
+        FieldInfo.checkFieldsContiguity(fieldsInfo);
+    }
+
+    public static void main(String[] args) {
+        H h = new H();
+        testFieldsContiguity(h.getClass());
+        B b = new B();
+        testFieldsContiguity(b.getClass());
+    }
+}
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Tue Feb 11 13:41:48 2020 +0530
@@ -99,9 +99,11 @@
         } catch (Throwable t){
             t.printStackTrace(ERR);
         } finally {
-            try {
-                OUT.close();
-            } catch (Throwable ignore) {
+            if (OUT != System.out) {
+                try {
+                    OUT.close();
+                } catch (Throwable ignore) {
+                }
             }
             // <clinit> might have started new threads
             System.exit(passed ? 0 : 1);
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Tue Feb 11 13:41:48 2020 +0530
@@ -150,6 +150,9 @@
             } else {
                 compileAtLevel(compLevel);
             }
+
+            // Make the method eligible for sweeping sooner
+            WHITE_BOX.deoptimizeMethod(method);
         }
 
         private void waitCompilation() {
--- a/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java	Tue Feb 11 13:41:48 2020 +0530
@@ -49,7 +49,7 @@
 import jdk.test.lib.process.ProcessTools;
 
 public class Test {
-    private static String UNSUPPORTED_OPTION_MESSAGE = "-XX:TieredCompilation not supported in this VM";
+    private static String UNSUPPORTED_OPTION_MESSAGE = "-XX:+TieredCompilation not supported in this VM";
     private static String REGEXP = "^[0-9.]+: \\[compile level=\\d";
     public static void main(String[] args) throws Exception {
         {
@@ -59,7 +59,7 @@
                     "-XX:+PrintTieredEvents",
                     "-version");
             var output = new OutputAnalyzer(pb.start());
-            if (output.getStdout().contains(UNSUPPORTED_OPTION_MESSAGE)) {
+            if (output.getStderr().contains(UNSUPPORTED_OPTION_MESSAGE)) {
                 throw new SkippedException(UNSUPPORTED_OPTION_MESSAGE);
             }
             output.shouldHaveExitValue(0)
--- a/test/jdk/ProblemList.txt	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/ProblemList.txt	Tue Feb 11 13:41:48 2020 +0530
@@ -913,9 +913,6 @@
 
 com/sun/jdi/NashornPopFrameTest.java                            8225620 generic-all
 
-com/sun/jdi/JdwpListenTest.java                                 8234935 windows-all
-com/sun/jdi/JdwpAttachTest.java                                 8234935 windows-all
-
 ############################################################################
 
 # jdk_time
--- a/test/jdk/com/sun/jdi/JdwpAttachTest.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/com/sun/jdi/JdwpAttachTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -25,6 +25,7 @@
 import com.sun.jdi.VirtualMachine;
 import com.sun.jdi.connect.Connector;
 import com.sun.jdi.connect.ListeningConnector;
+import jdk.test.lib.Platform;
 import jdk.test.lib.apps.LingeredApp;
 
 import java.net.Inet4Address;
@@ -33,7 +34,6 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
-import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -54,8 +54,6 @@
  */
 public class JdwpAttachTest {
 
-    private static final boolean IsWindows = System.getProperty("os.name").toLowerCase().contains("windows");
-
     // Set to true to perform testing of attach from wrong address (expected to fail).
     // It's off by default as it caused significant test time increase\
     // (tests <number_of_addresses> * <number_of_addresses> cases, each case fails by timeout).
@@ -115,7 +113,7 @@
         }
         log("  Listening port: " + port);
 
-        log("  Attaching from " + connectAddress);
+        log("  Attaching to " + connectAddress);
         try {
             ExecutorService executor = Executors.newSingleThreadExecutor();
             executor.submit((Callable<Exception>)() -> {
@@ -155,6 +153,12 @@
         list.add(addr);
     }
 
+    private static boolean isTeredo(Inet6Address addr) {
+        // Teredo prefix is 2001::/32 (i.e. first 4 bytes are 2001:0000)
+        byte[] bytes = addr.getAddress();
+        return bytes[0] == 0x20 && bytes[1] == 0x01 && bytes[2] == 0x00 && bytes[3] == 0x00;
+    }
+
     private static List<InetAddress> getAddresses() {
         List<InetAddress> result = new LinkedList<>();
         try {
@@ -173,6 +177,12 @@
                             // On other platforms test both symbolic and numeric scopes.
                             if (addr instanceof Inet6Address) {
                                 Inet6Address addr6 = (Inet6Address)addr;
+                                // Teredo clients cause intermittent errors on listen ("bind failed")
+                                // and attach ("no route to host").
+                                // Teredo is supposed to be a temporary measure, but some test machines have it.
+                                if (isTeredo(addr6)) {
+                                    continue;
+                                }
                                 NetworkInterface scopeIface = addr6.getScopedInterface();
                                 if (scopeIface != null && scopeIface.getName() != null) {
                                     // On some test machines VPN creates link local addresses
@@ -190,7 +200,7 @@
                                         throw new RuntimeException("Unexpected", e);
                                     }
 
-                                    if (IsWindows) {
+                                    if (Platform.isWindows()) {
                                         // don't add addresses with symbolic scope
                                         continue;
                                     }
--- a/test/jdk/com/sun/jdi/JdwpListenTest.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/com/sun/jdi/JdwpListenTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 import com.sun.jdi.connect.AttachingConnector;
 import com.sun.jdi.connect.Connector;
 import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import jdk.test.lib.Platform;
 import lib.jdb.Debuggee;
 
 import java.io.IOException;
@@ -52,8 +53,6 @@
  */
 public class JdwpListenTest {
 
-    private static final boolean IsWindows = System.getProperty("os.name").toLowerCase().contains("windows");
-
     // Set to true to allow testing of attach from wrong address (expected to fail).
     // It's off by default as it causes test time increase and test interference (see JDK-8231915).
     private static boolean allowNegativeTesting = false;
@@ -89,7 +88,7 @@
 
     private static void listenTest(String listenAddress, String connectAddress, boolean expectedResult)
             throws IOException {
-        log("\nTest: listen at " + listenAddress + ", attaching from " + connectAddress
+        log("\nTest: listen at " + listenAddress + ", attaching to " + connectAddress
                 + ", expected: " + (expectedResult ? "SUCCESS" : "FAILURE"));
         if (!expectedResult && !allowNegativeTesting) {
             log("SKIPPED: negative testing is disabled");
@@ -99,7 +98,7 @@
         log("Starting listening debuggee at " + listenAddress);
         try (Debuggee debuggee = Debuggee.launcher("HelloWorld").setAddress(listenAddress + ":0").launch()) {
             log("Debuggee is listening on " + listenAddress + ":" + debuggee.getAddress());
-            log("Connecting from " + connectAddress + ", expected: " + (expectedResult ? "SUCCESS" : "FAILURE"));
+            log("Connecting to " + connectAddress + ", expected: " + (expectedResult ? "SUCCESS" : "FAILURE"));
             try {
                 VirtualMachine vm = attach(connectAddress, debuggee.getAddress());
                 vm.dispose();
@@ -120,6 +119,12 @@
         list.add(addr);
     }
 
+    private static boolean isTeredo(Inet6Address addr) {
+        // Teredo prefix is 2001::/32 (i.e. first 4 bytes are 2001:0000)
+        byte[] bytes = addr.getAddress();
+        return bytes[0] == 0x20 && bytes[1] == 0x01 && bytes[2] == 0x00 && bytes[3] == 0x00;
+    }
+
     private static List<InetAddress> getAddresses() {
         List<InetAddress> result = new LinkedList<>();
         try {
@@ -138,6 +143,12 @@
                             // On other platforms test both symbolic and numeric scopes.
                             if (addr instanceof Inet6Address) {
                                 Inet6Address addr6 = (Inet6Address)addr;
+                                // Teredo clients cause intermittent errors on listen ("bind failed")
+                                // and attach ("no route to host").
+                                // Teredo is supposed to be a temporary measure, but some test machines have it.
+                                if (isTeredo(addr6)) {
+                                    continue;
+                                }
                                 NetworkInterface scopeIface = addr6.getScopedInterface();
                                 if (scopeIface != null && scopeIface.getName() != null) {
                                     // On some test machines VPN creates link local addresses
@@ -155,7 +166,7 @@
                                         throw new RuntimeException("Unexpected", e);
                                     }
 
-                                    if (IsWindows) {
+                                    if (Platform.isWindows()) {
                                         // don't add addresses with symbolic scope
                                         continue;
                                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/ssltest/Cert.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * The certificates used by this test.
+ * They are generated by script gen-certs.sh.
+ */
+public enum Cert {
+
+    /*
+     * Version: 3 (0x2)
+     * Serial Number:
+     *     65:24:13:3c:7a:98:0c:16:a2:91:9c:8e:42:84:cf:be:be:d2:f1:42
+     * Signature Algorithm: sha256WithRSAEncryption
+     * Issuer: CN = evil
+     * Validity
+     *     Not Before: Feb  8 03:59:27 2020 GMT
+     *     Not After : Feb  5 03:59:27 2030 GMT
+     * Subject: CN = evil
+     * X509v3 extensions:
+     *     X509v3 Subject Key Identifier:
+     *         09:D0:E8:51:6C:0F:88:59:47:D1:FD:05:C2:00:10:D6:A4:80:04:07
+     *     X509v3 Authority Key Identifier:
+     *         keyid:09:D0:E8:51:6C:0F:88:59:47:D1:FD:05:C2:00:10:D6:A4:80:04:07
+     */
+    BAD_CERT(
+        "RSA",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIC7jCCAdagAwIBAgIUZSQTPHqYDBaikZyOQoTPvr7S8UIwDQYJKoZIhvcNAQEL\n" +
+        "BQAwDzENMAsGA1UEAwwEZXZpbDAeFw0yMDAyMDgwMzU5MjdaFw0zMDAyMDUwMzU5\n" +
+        "MjdaMA8xDTALBgNVBAMMBGV2aWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" +
+        "AoIBAQCmirsTOW1G+LoI/Aj59lMk3KLywAbXASeTdnBoWkchuJ0QJWO/5b5kgf6Q\n" +
+        "VFfe9lXof9psGIKaCGq6KsI0uqj7+7y++//l+E6GB8UshVB8MXc1SLFe8AxPYhWC\n" +
+        "TXaKWyWGl7PXvugzbByFrf4IwE9+6phYkvl/zHvaMKqdwnkpXuyuBgT3BiYTSNsx\n" +
+        "k1Ma+s5rqiwsOODSzwhadwmU9T4z11KypYb/DixJgHvUET4gTB+i3ll+PllVdQtX\n" +
+        "zBLpEuj5HadK0PsqlOIok3eoSU+MpRqsz0gFEQ95y+Les3MlBeQ7fVKBz8GbrFDB\n" +
+        "Atzca+iknEh8fkLIUUuCjTjUtLvfAgMBAAGjQjBAMB0GA1UdDgQWBBQJ0OhRbA+I\n" +
+        "WUfR/QXCABDWpIAEBzAfBgNVHSMEGDAWgBQJ0OhRbA+IWUfR/QXCABDWpIAEBzAN\n" +
+        "BgkqhkiG9w0BAQsFAAOCAQEAQMfPfYfVSSdsiEUOlVg6M5D90HRONzqlg/v0RqQI\n" +
+        "fb3uufXJs20dg8iamVORXIIeUpGv1OQ2Rx4ndnV3bRLK6ep3gswIkOnD8z/CeNgl\n" +
+        "odZPvWyklHTMenGqU2TR3ceFep/DvQkrP4aZWyr3e2fjatKR/s4pXgBwHs/hR76O\n" +
+        "vDYLRDyCG/+MtUClFsc9HLedbU4Wp8JyaafFZ63/VjaIcvdHoDGNILRu5AIN/JVM\n" +
+        "Sgz4blkWJxS1dlqBYwxvbpJWrHUcktsa3Bzw2zWOkTVGQJi3pMvzRBkgliNaXPi3\n" +
+        "qcPViqgzVoB4QdOQBnvDtQ9+8Nt/dQY1VJFSBLxZQIefiQ==\n" +
+        "-----END CERTIFICATE-----",
+        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmirsTOW1G+LoI\n" +
+        "/Aj59lMk3KLywAbXASeTdnBoWkchuJ0QJWO/5b5kgf6QVFfe9lXof9psGIKaCGq6\n" +
+        "KsI0uqj7+7y++//l+E6GB8UshVB8MXc1SLFe8AxPYhWCTXaKWyWGl7PXvugzbByF\n" +
+        "rf4IwE9+6phYkvl/zHvaMKqdwnkpXuyuBgT3BiYTSNsxk1Ma+s5rqiwsOODSzwha\n" +
+        "dwmU9T4z11KypYb/DixJgHvUET4gTB+i3ll+PllVdQtXzBLpEuj5HadK0PsqlOIo\n" +
+        "k3eoSU+MpRqsz0gFEQ95y+Les3MlBeQ7fVKBz8GbrFDBAtzca+iknEh8fkLIUUuC\n" +
+        "jTjUtLvfAgMBAAECggEATyu2QS5Un5+QOMMvtTx/TA/DOulElyNKYBS23TTFiedM\n" +
+        "ayeLIuehuf/+NziRSUILlupouGhyda04p2W6SvzNZnTGxnffr8B5+8dn2YFKwK93\n" +
+        "PxJel4ZAI+C53ubaSm2IClLFwPNVSVTEvlv3XsulPu1hHQJJr5JS8meeRD72AE8G\n" +
+        "brKbLlq6OGey6u9teao0m4Wo05MzaEoOx4fztPP4BiJJobuPYrdthUwfXJ2mQYeg\n" +
+        "fJKl+JeLUnAXmq8e+6Zs88NzGK8Gmd2TvGnUahxSDtXHuRkB2lOrGFrEJKkAXDBx\n" +
+        "2q8r3vvcay6+k95fS2HOvggFDALS37BGckWg4+HYuQKBgQDXkxw0u2G7rCYbF691\n" +
+        "jil++DLNUzejZonAvA/cceVHShfAMlWCBf58cLNsY33rkRsFazhrdDoDAFqKxejB\n" +
+        "xWM8U7UHiHZSznuXTL0YbUombfz+0lp/KwXcirnB7O3AdIW4lfMo/ozeMMIuEzsL\n" +
+        "G/MDvbNSdawEso/qtxFvz87ctQKBgQDFxcCSyWb/SQVr3RkZkO3BW2efuANxNeUh\n" +
+        "35L4inWTa8ml8UL4SrTrkfUHzu5TnBGbSb2n8CdkPnInA81dKagX6LXuONeLkX/e\n" +
+        "RXyWIwWRiBkpYSaw2OGApl49DRvk2kCzwoVRWwh8qfhpC0P6AClFRaVAovYcTxm3\n" +
+        "vhCJL3jmwwKBgGMLvTbhLStMEgn6nOwXECu9H6JE7NhPgVUjUupHDj/t4/GzbqQZ\n" +
+        "2u4T3ewb3jwAZHjd5YNBWHIOlIsUGTgGV+zczN0ULsEnC5Pddzgk5p+3gzkVLu0k\n" +
+        "uEG3H1fhYu882j+P7bPVGKXxoxYGUedtxP7gBucJF6rk28jMqd9EjFfNAoGBAKcc\n" +
+        "ASwGodDzknEh0SOZIkxPP6/lfIMcVw/YKgd4dwCqAykEQuIpvdWO7sw6PYbISNg9\n" +
+        "5tMQSTiayznMLKqbmD0blR5FSVvVBYZ6kFsMHJhrt1cPj/G+UEy0RsyvVvJ4uFMr\n" +
+        "+hpUIUe1FwErU7TajgTKZGfJSsuAyupG3xIL2syhAoGALv+ulZAY/gUKH8NigsXo\n" +
+        "pFPTpiXMyTD/O4RUH/5LcxDELVZ8cnV2q3qEX+ep24y0AtNiBx4oHpZ/vIxtwBCR\n" +
+        "JKU2xmIGC6NyQMRSzfmNgi0X450rgKbTAxn/LAU8syXmNpBUrFZ8+02pQvWzxqfU\n" +
+        "zGaMEK3+f1sq8Byzau/qhKU="),
+
+    /*
+     * Version: 3 (0x2)
+     * Serial Number:
+     *     70:41:2f:71:43:d1:67:b5:29:c6:3e:ce:62:ba:d5:aa:4a:f1:f7:f0
+     * Signature Algorithm: sha256WithRSAEncryption
+     * Issuer: CN = localhost
+     * Validity
+     *     Not Before: Feb  8 03:59:18 2020 GMT
+     *     Not After : Feb  5 03:59:18 2030 GMT
+     * Subject: CN = localhost
+     * X509v3 extensions:
+     *     X509v3 Subject Key Identifier:
+     *         12:65:C7:4B:D8:77:D8:55:6E:2D:AF:C4:F8:09:FE:08:F4:22:EA:D5
+     *     X509v3 Authority Key Identifier:
+     *         keyid:12:65:C7:4B:D8:77:D8:55:6E:2D:AF:C4:F8:09:FE:08:F4:22:EA:D5
+     */
+    GOOD_CERT(
+        "RSA",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIC+DCCAeCgAwIBAgIUcEEvcUPRZ7Upxj7OYrrVqkrx9/AwDQYJKoZIhvcNAQEL\n" +
+        "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDIwODAzNTkxOFoXDTMwMDIw\n" +
+        "NTAzNTkxOFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\n" +
+        "AAOCAQ8AMIIBCgKCAQEAtSOmfkF0zjPeZ4DDsJZO3OaDq+XHtPLB+xvri1iuL9b+\n" +
+        "dZDXOqPZ5+koWM9NzDR6Um+IN46oTU+8eJw+hYcZaE9tzS9kH+6qOBk/827yEyVa\n" +
+        "jh9Wqw164xj16QPyQJuHEeeDJ7elNfaOQXRu2UqZB9suKbolqsHe42hbg0/tbln7\n" +
+        "C8C6qEJOpnEaapFHi3/3AeoQQ57zywqrzopeiiuUDWmBhXY30ve33RrJl/OIM1sB\n" +
+        "QSoVCPcaF0mXaDwUTYIksxelon1K9PJa76p9ybGnsxkYfCAGZ8O+fTjJfQONU+Gu\n" +
+        "zOmcyXL5D5O/nI8lxN8hbZwVIAYXLYRUonECIOJ/iQIDAQABo0IwQDAdBgNVHQ4E\n" +
+        "FgQUEmXHS9h32FVuLa/E+An+CPQi6tUwHwYDVR0jBBgwFoAUEmXHS9h32FVuLa/E\n" +
+        "+An+CPQi6tUwDQYJKoZIhvcNAQELBQADggEBAFatzXsT9YZ0TF66G6apSbbs6mH9\n" +
+        "PMVE9IuE4yv2zyKofSMmDHFdmfNdkMHWkIxcZKuiL00IPFL76LAb9DWNQVy4otq6\n" +
+        "3+n0CCi808gDNUMYMQLlXVooZsByXuMuokyg29F5mWEH4rswU6ru33lAB7CT7BuN\n" +
+        "z5/eUhxTcXcJV6pLgcEM68NIc755PULevmqmd8SrVgcFjkxAFOsYd9L86wYLdiPO\n" +
+        "uXfN/EjLMGHG2gpEqHEzQpEEAA/IsCJ1HQ8vvGkeggUIXPrwlIMbQcz/8WBSDel5\n" +
+        "hvVRmADJCLf/0IwxKsSOMWZ4OMmcXMjxnae3lWPQomlzWHMZlFraG2rE/Vo=\n" +
+        "-----END CERTIFICATE-----",
+        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1I6Z+QXTOM95n\n" +
+        "gMOwlk7c5oOr5ce08sH7G+uLWK4v1v51kNc6o9nn6ShYz03MNHpSb4g3jqhNT7x4\n" +
+        "nD6FhxloT23NL2Qf7qo4GT/zbvITJVqOH1arDXrjGPXpA/JAm4cR54Mnt6U19o5B\n" +
+        "dG7ZSpkH2y4puiWqwd7jaFuDT+1uWfsLwLqoQk6mcRpqkUeLf/cB6hBDnvPLCqvO\n" +
+        "il6KK5QNaYGFdjfS97fdGsmX84gzWwFBKhUI9xoXSZdoPBRNgiSzF6WifUr08lrv\n" +
+        "qn3JsaezGRh8IAZnw759OMl9A41T4a7M6ZzJcvkPk7+cjyXE3yFtnBUgBhcthFSi\n" +
+        "cQIg4n+JAgMBAAECggEAD2O4AYIOKna9ro2CEr6ydJIhHbmn/feiA3Obz3r5UZcy\n" +
+        "h0qG/rRtDwcAJot2UKMkwVw4dn/oTKk5mgWsSivwPKyC56vfFddxHtMGW+hRKM9D\n" +
+        "ok+HTYEXr7OvMNzk+Bg+oYbJ3dX8c1k/PNBnmo578e7tPR5TlO5jwW5cWAuyYG2f\n" +
+        "+YUCqMNe02yZvvlvK1kOSSgqlNH0S14/hVZTYkyxXMCCrkxPFXh5j8w6ZUzVipXg\n" +
+        "99EYcRdq7dA3XVBSgQQ4m5772FIIzlBn8LdIIfw3VQrtZ9HapowLk6QdcHSHBKMK\n" +
+        "0rqb1PlG2ynD2n8hKn4MssJ+tkzvbGrQcLjL/+XHAQKBgQDmiOIke90T8puq3FkN\n" +
+        "NlgdBA9Zem5U2t3TvtQa36cuO/paYrLaVK5U0ucNZ9d4i6avdyp8TyKJrUHDcazi\n" +
+        "QkDpjxb0KBhisutDZ4o1JFW4ZtB3zwIGIYWBBIE1kRIc0ucYoAurSdOmAsKq6XJQ\n" +
+        "B0CQYBJPrTHq5niCl0tKPtrISwKBgQDJJfNcKSz46zdnqsNZAmL+q+cMQf4txiCS\n" +
+        "v0JefOeKKlwNcYWxRgf1yTNENamKKh8wyqOhc/OkxXjglRo9BFMt6BFFARzDddWE\n" +
+        "Wo18cyLc2WvTTv2FCZ0J/eF1jPTGJsTpCU6Prbt4XPjZpzSTF2cQR7CxLp15FsJm\n" +
+        "2LMcQ8ma+wKBgQC72So8hFme2X+S+D3wECo4aoh/Zs3kgvtigQqgY0H84I6de/M1\n" +
+        "CO+M2tW/DLB8336RV87cwDbqbK07rrMrIsV2C0yu4sUMF7Kwl/v8VYEr40tXdOy3\n" +
+        "RjVc7ejDV1Sk/A2m+TLI/j1h9rndPqARKfeoLUB+gCg+ulHUR6fn9dOchQKBgByx\n" +
+        "uj6qbQzxWQ0D0iwvZ/nWgfZAr8bN3bWxbQFXphwSoOEWEbFRQS9xzUtssEvSaHKo\n" +
+        "ZaFRji8yMGUxP/X2WPtSgKwsVXMYqyXfWRGoxw9kQLp7KTVCQtG7Et+XBRADVdG8\n" +
+        "jyV17ilkcedyr9BP5VbwMyeDc9ljQsYzIZHlpavjAoGAct8Wktj0hegCoTxSukU1\n" +
+        "SkJ7t4376sSfxVbbUrH86Y1Z55le1O+VkGtqETmk+Q8qf5Ymnal3W9zZ0O9mOE04\n" +
+        "otFbiB3ifUbpBAipyxS06SIFwMctmSk2EqBcXa3nZ9eUGqx0JhoQahfyDkFzfwJY\n" +
+        "hiBTWnlMjCiJ40yRYAWDzZg="),
+
+    /*
+     * Version: 3 (0x2)
+     * Serial Number:
+     *     3f:62:91:39:7e:02:e9:77:20:61:ce:7e:a2:3c:c0:6c:3f:2e:08:49
+     * Signature Algorithm: sha256WithRSAEncryption
+     * Issuer: CN = UNKOWN
+     * Validity
+     *     Not Before: Feb  8 04:00:04 2020 GMT
+     *     Not After : Feb  5 04:00:04 2030 GMT
+     * Subject: CN = unknown
+     * X509v3 extensions:
+     *     X509v3 Subject Key Identifier:
+     *         F7:D7:AE:80:DF:EC:7A:60:5A:E8:62:60:70:03:B6:BD:23:05:19:62
+     *     X509v3 Authority Key Identifier:
+     *         keyid:F7:D7:AE:80:DF:EC:7A:60:5A:E8:62:60:70:03:B6:BD:23:05:19:62
+     *     X509v3 Subject Alternative Name:
+     *         IP Address:127.0.0.1
+     */
+    LOOPBACK_CERT(
+        "RSA",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDBTCCAe2gAwIBAgIUP2KROX4C6XcgYc5+ojzAbD8uCEkwDQYJKoZIhvcNAQEL\n" +
+        "BQAwEjEQMA4GA1UEAwwHdW5rbm93bjAeFw0yMDAyMDgwNDAwMDRaFw0zMDAyMDUw\n" +
+        "NDAwMDRaMBIxEDAOBgNVBAMMB3Vua25vd24wggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" +
+        "DwAwggEKAoIBAQC8dBwc+nhzuGOcqmeQkcms6JrUPDPcvq6gEEH3dxorzngfxrsl\n" +
+        "lfM6SPJBV4A7HVEcsGhcMoPzzpFVISi3XyLkGuw2WnEW6nKcB2QgaS0Ub8PoDZ7P\n" +
+        "erWGOIjHF1slKxX40tZBiEp1oJANDq7CzSGWiyTorCjbX6OiWZCbhQkw+SpXrAdD\n" +
+        "fzjEAr3y8cgsC7qqTxoz/T9C1+UMmzc88kpAqih7jj2L/i6387dBmV+zrMsNyO0Q\n" +
+        "UPGACzMiSZV3tiwYA6cvDY3WS3fCwLSYUWdHi1orerHQuGOHLK4eyPVDcvuQdUJ/\n" +
+        "T0+jbNZa51scqrBUT/aDlCMCxFUY3vquz2xfAgMBAAGjUzBRMB0GA1UdDgQWBBT3\n" +
+        "166A3+x6YFroYmBwA7a9IwUZYjAfBgNVHSMEGDAWgBT3166A3+x6YFroYmBwA7a9\n" +
+        "IwUZYjAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBcfcv2J73T\n" +
+        "nHFsCPU3WM6UW2uE8BIM/s/VbjkV1nalFyHi/TU6CN01sDymTABhzIlx5N6PW0HP\n" +
+        "Z0q1C7l1nsoQHwmJO+avOHu3ZjDrLMpU6wTQLEemTd3R5HTyA3/I/FUVFHeuLwJg\n" +
+        "L7OLNc8ouT1hkiIZD+xKwfCEdT3o+ldB+9L4WYRJPt2W3bf3W/yM8JmwW8uf6+U3\n" +
+        "V46xiE5GoOKoIkeAkBAaIbepsZH9rPb7alBSgYgwQYDft9wuGMeNcvPvgVsXjA7I\n" +
+        "RafJVdxVinVMEaOjckIZ5WlrR5667aIJapZH1r7/tiSQCRaJcILx7pL4x8C+x34z\n" +
+        "dPHbbyP/Rdq9\n" +
+        "-----END CERTIFICATE-----",
+        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8dBwc+nhzuGOc\n" +
+        "qmeQkcms6JrUPDPcvq6gEEH3dxorzngfxrsllfM6SPJBV4A7HVEcsGhcMoPzzpFV\n" +
+        "ISi3XyLkGuw2WnEW6nKcB2QgaS0Ub8PoDZ7PerWGOIjHF1slKxX40tZBiEp1oJAN\n" +
+        "Dq7CzSGWiyTorCjbX6OiWZCbhQkw+SpXrAdDfzjEAr3y8cgsC7qqTxoz/T9C1+UM\n" +
+        "mzc88kpAqih7jj2L/i6387dBmV+zrMsNyO0QUPGACzMiSZV3tiwYA6cvDY3WS3fC\n" +
+        "wLSYUWdHi1orerHQuGOHLK4eyPVDcvuQdUJ/T0+jbNZa51scqrBUT/aDlCMCxFUY\n" +
+        "3vquz2xfAgMBAAECggEAEcYNpLoGxDs+wdbcf6kQUUt61st6xLYDODtwTUuhX0JQ\n" +
+        "2AZhPjE/SF764ijDgk/Ih6EnppJpGYSA9ntzIKBLZSIY5yNuiQ/BkW+tBNWGl+fW\n" +
+        "nTszoDPdjPQmCkjsorvGjbos1O9qvl9PVrvsxZidM1qaN4uNKuuBPl2eItzQOhsM\n" +
+        "YFbmw1nqSX31gukv9a6yM2VgDUiGMlEGwkOphutbqt+wTO+9hEopGZHB7mNc5NO9\n" +
+        "foWVVI1rzS2yR2d85lsG4YBqBMDp2s2cBofIAe/SSSpBYPR4RfEBDpSaVceR4+cL\n" +
+        "Lq52DhLVe/zgVj7LEGdyTZTQxw414sRBIz8KXcRIkQKBgQDon26R0/vToZcxgnpr\n" +
+        "ososGh+iTov883DCxX30sntl/GbyUhg50q7Tq5mXGyzodoFHGTL+bOcU3g5O4MOV\n" +
+        "6HlTFe1dUjyC7M0ah6NaCSsl4SPTxtWjeHMBMhNisInDAO+ju4MJAhgoHuYL6p39\n" +
+        "NDmKSDtpaegFz1Q64C1Ea9fsFwKBgQDPZFvQNjSCm06ObsfXLZKS6IEqgGbihMfM\n" +
+        "cv/HjIpAKXNp/Y6Y/YmdFBpdHDkOJ9BXwJqTuMuM69BuldvNXkkY7zrhPFPawWyF\n" +
+        "O/N1aMNCT89AreBwXMYmgG9yLm1EF1FOuz2oAnWWpcUHBups+cZQikYSQxcOSqrL\n" +
+        "bNTEWffG+QKBgDTk+8lhAGQQ3EY/uwJ6k6oPjp3jamVsHXnMWmWnp/N6vxXeoO+U\n" +
+        "/nfXDyeS4FVDjQXTrwq3TJwsGejJpu+RWvUPiVes+WFz4vdjXDt+1jbYyMLA9Zck\n" +
+        "LlJZRpssNUcIEXWTj6oetct5qymOgbovg93zqr6/fCjGCgsRKnniY8ilAoGAcWGH\n" +
+        "hGQt/v1TTDEqVexXRrOP8iFyngJDjPWN+pVN+9ftfhOeAuwRcOvNofvNAX0ovODS\n" +
+        "YVJVDfzZ3atWGIekZNpdEUg++8hlQM3OwvB8V2N0hgLJQgSmW+Q5iW3yVJh+3hEl\n" +
+        "mxWFHdAQ0E+ql9tR3TRLLK67CxgtGbus8o/RE1kCgYAuf9o6Q++l8H0vNZTnzBNu\n" +
+        "bt0QnLxyh7RuViYuCkzLK+jGftgadVfsRgnOKvxQkMzcXfBgpV5JcVKXtaxDhPxM\n" +
+        "xHwblgOEGlrD4tAwvtPw3GLhmD4Shy8zcT0Lwto81fquskA5yyDGJxbq9CMzWk3w\n" +
+        "dSOT2C7lwW+hkycUio/fTQ==");
+
+    public final String keyAlgo;
+    public final String certStr;
+    public final String keyStr;
+
+    private Cert(String keyAlgo, String certStr, String keyStr) {
+        this.keyAlgo = keyAlgo;
+        this.certStr = certStr;
+        this.keyStr = keyStr;
+    }
+}
--- a/test/jdk/java/net/httpclient/ssltest/CertificateTest.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/java/net/httpclient/ssltest/CertificateTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,36 +21,41 @@
  * questions.
  */
 
-import java.io.File;
+import static java.net.http.HttpClient.Builder.NO_PROXY;
+
 import java.io.IOException;
 import java.net.URI;
 import java.net.http.HttpClient;
-import java.net.http.HttpResponse.BodyHandlers;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
+
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLParameters;
-import static java.net.http.HttpClient.Builder.NO_PROXY;
+
+import jdk.test.lib.security.KeyEntry;
+import jdk.test.lib.security.KeyStoreUtils;
+import jdk.test.lib.security.SSLContextBuilder;
 
 /*
  * @test
+ * @library /test/lib
  * @build Server CertificateTest
- * @run main/othervm CertificateTest good.keystore expectSuccess
- * @run main/othervm CertificateTest bad.keystore expectFailure
+ * @run main/othervm CertificateTest GOOD_CERT expectSuccess
+ * @run main/othervm CertificateTest BAD_CERT expectFailure
  * @run main/othervm
  *      -Djdk.internal.httpclient.disableHostnameVerification
- *       CertificateTest bad.keystore expectSuccess
+ *       CertificateTest BAD_CERT expectSuccess
  * @run main/othervm
  *      -Djdk.internal.httpclient.disableHostnameVerification=true
- *       CertificateTest bad.keystore expectSuccess
+ *       CertificateTest BAD_CERT expectSuccess
  * @run main/othervm
  *      -Djdk.internal.httpclient.disableHostnameVerification=false
- *       CertificateTest bad.keystore expectFailure
+ *       CertificateTest BAD_CERT expectFailure
  * @run main/othervm
  *      -Djdk.internal.httpclient.disableHostnameVerification=xxyyzz
- *       CertificateTest bad.keystore expectFailure
- * @run main/othervm CertificateTest loopback.keystore expectSuccess
+ *       CertificateTest BAD_CERT expectFailure
+ * @run main/othervm CertificateTest LOOPBACK_CERT expectSuccess
  */
 
 /**
@@ -59,25 +64,24 @@
  * by the server for its own identity. Two servers on two different ports are used
  * on the remote end.
  *
- * For the "good" run the cert contains the correct hostname of the target server
+ * The GOOD_CERT cert contains the correct hostname of the target server
  * and therefore should be accepted by the cert checking code in the client.
- * For the "bad" run, the cert contains an invalid hostname, and should be rejected.
+ * The BAD_CERT cert contains an invalid hostname, and should be rejected.
+ * The LOOPBACK_CERT cert contains an invalid hostname, but it also contains a
+ * subject alternative name for IP address 127.0.0.1, so it should be accepted
+ * for this address.
  */
 public class CertificateTest {
-    static SSLContext ctx;
-    static SSLParameters params;
+
+    private static Cert cert;
     static boolean expectSuccess;
-    static String trustStoreProp;
     static Server server;
     static int port;
 
-    static String TESTSRC = System.getProperty("test.src");
     public static void main(String[] args) throws Exception
     {
         try {
-            String keystore = args[0];
-            trustStoreProp = TESTSRC + File.separatorChar + keystore;
-
+            String certName = args[0];
             String passOrFail = args[1];
 
             if (passOrFail.equals("expectSuccess")) {
@@ -85,38 +89,44 @@
             } else {
                 expectSuccess = false;
             }
-            server = new Server(trustStoreProp);
+
+            cert = Cert.valueOf(certName);
+            server = new Server(getSSLContext(cert));
             port = server.getPort();
-            System.setProperty("javax.net.ssl.trustStore", trustStoreProp);
-            System.setProperty("javax.net.ssl.trustStorePassword", "passphrase");
-            init();
-            test(args);
+            test(cert);
         } finally {
-            server.stop();
+            if (server != null) {
+                server.stop();
+            }
         }
     }
 
-    static void init() throws Exception
-    {
-        ctx = SSLContext.getDefault();
-        params = ctx.getDefaultSSLParameters();
-        //params.setProtocols(new String[] { "TLSv1.2" });
+    private static SSLContext getSSLContext(Cert cert) throws Exception {
+        SSLContextBuilder builder = SSLContextBuilder.builder();
+        builder.trustStore(
+                KeyStoreUtils.createTrustStore(new String[] { cert.certStr }));
+        builder.keyStore(KeyStoreUtils.createKeyStore(
+                new KeyEntry[] { new KeyEntry(cert.keyAlgo,
+                        cert.keyStr, new String[] { cert.certStr }) }));
+        return builder.build();
     }
 
-    static void test(String[] args) throws Exception
+    static void test(Cert cert) throws Exception
     {
         String uri_s;
-        if (args[0].equals("loopback.keystore"))
+        if (cert == Cert.LOOPBACK_CERT)
             uri_s = "https://127.0.0.1:" + Integer.toString(port) + "/foo";
         else
             uri_s = "https://localhost:" + Integer.toString(port) + "/foo";
         String error = null;
         Exception exception = null;
         System.out.println("Making request to " + uri_s);
+
+        SSLContext ctx = getSSLContext(cert);
         HttpClient client = HttpClient.newBuilder()
                 .proxy(NO_PROXY)
                 .sslContext(ctx)
-                .sslParameters(params)
+                .sslParameters(ctx.getDefaultSSLParameters())
                 .build();
 
         HttpRequest request = HttpRequest.newBuilder(new URI(uri_s))
--- a/test/jdk/java/net/httpclient/ssltest/Server.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/java/net/httpclient/ssltest/Server.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,12 +22,10 @@
  */
 
 import com.sun.net.httpserver.*;
+
 import java.io.*;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.net.URI;
-import java.security.*;
-import java.util.*;
 import java.util.logging.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
@@ -44,17 +42,17 @@
 
     // assuming the TLS handshake succeeds, the server returns a 200 OK
     // response with a short text string.
-    public Server(String certfile) throws Exception {
+    public Server(SSLContext ctx) throws Exception {
         initLogger();
-        SSLContext ctx = getContext("TLSv1.2", certfile);
         Configurator cfg = new Configurator(ctx);
-        InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(),0);
+        InetSocketAddress addr = new InetSocketAddress(
+                InetAddress.getLoopbackAddress(), 0);
         server = HttpsServer.create(addr, 10);
         server.setHttpsConfigurator(cfg);
         server.createContext("/", new MyHandler());
-        server.setExecutor((exec=Executors.newCachedThreadPool()));
+        server.setExecutor((exec = Executors.newCachedThreadPool()));
         port = server.getAddress().getPort();
-        System.out.println ("Listening on port " + port);
+        System.out.println("Listening on port " + port);
         server.start();
     }
 
@@ -67,22 +65,6 @@
         exec.shutdownNow();
     }
 
-    SSLContext getContext(String protocol, String certfile) throws Exception {
-        char[] passphrase = "passphrase".toCharArray();
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(new FileInputStream(certfile), passphrase);
-
-        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
-        kmf.init(ks, passphrase);
-
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
-        tmf.init(ks);
-
-        SSLContext ssl = SSLContext.getInstance(protocol);
-        ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-        return ssl;
-    }
-
     Logger logger;
 
     void initLogger() {
@@ -120,7 +102,7 @@
             SSLParameters p = getSSLContext().getDefaultSSLParameters();
             for (String cipher : p.getCipherSuites())
                 System.out.println("Cipher: " + cipher);
-            System.err.println("PArams = " + p);
+            System.err.println("Params = " + p);
             params.setSSLParameters(p);
         }
     }
Binary file test/jdk/java/net/httpclient/ssltest/bad.keystore has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/ssltest/gen-certs.sh	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,53 @@
+# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# Generate OpenSSL configuration file
+echo "[req]" > openssl.conf
+echo "distinguished_name = dn" >> openssl.conf
+echo "x509_extensions = v3_ext" >> openssl.conf
+echo "[dn]" >> openssl.conf
+echo "[v3_ext]" >> openssl.conf
+echo "subjectKeyIdentifier = hash" >> openssl.conf
+echo "authorityKeyIdentifier = keyid" >> openssl.conf
+echo "basicConstraints = critical,CA:FALSE" >> openssl.conf
+
+# Generate X.509 version 3 extension file
+echo "subjectKeyIdentifier = hash" > v3.ext
+echo "authorityKeyIdentifier = keyid,issuer" >> v3.ext
+
+# Generate good cert
+openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -out good.key
+openssl req -config openssl.conf -new -key good.key -subj "/CN=localhost" -sha256 -out good.csr
+openssl x509 -extfile v3.ext -req -CAcreateserial -days 3650 -in good.csr -sha256 -signkey good.key -out good.cer
+
+# Generate bad cert
+openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -out bad.key
+openssl req -config openssl.conf -new -key bad.key -subj "/CN=evil" -sha256 -out bad.csr
+openssl x509 -extfile v3.ext -req -CAcreateserial -days 3650 -in bad.csr -sha256 -signkey bad.key -out bad.cer
+
+# Generate loopback cert with subject alternative name
+echo "subjectAltName = @alt_names" >> v3.ext
+echo "[alt_names]" >> v3.ext
+echo "IP.1 = 127.0.0.1" >> v3.ext
+
+openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -out loopback.key
+openssl req -config openssl.conf -new -key loopback.key -subj "/CN=unknown" -sha256 -out loopback.csr
+openssl x509 -extfile v3.ext -req -CAcreateserial -days 3650 -in loopback.csr -sha256 -signkey loopback.key -out loopback.cer
Binary file test/jdk/java/net/httpclient/ssltest/good.keystore has changed
Binary file test/jdk/java/net/httpclient/ssltest/loopback.keystore has changed
--- a/test/jdk/java/nio/channels/DatagramChannel/Loopback.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/java/nio/channels/DatagramChannel/Loopback.java	Tue Feb 11 13:41:48 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,9 @@
 import java.nio.channels.Selector;
 import java.util.List;
 import java.util.stream.Collectors;
-import static java.net.StandardProtocolFamily.*;
+import static java.net.StandardProtocolFamily.INET;
+import static java.net.StandardProtocolFamily.INET6;
+import static java.net.StandardSocketOptions.IP_MULTICAST_IF;
 import static java.net.StandardSocketOptions.IP_MULTICAST_LOOP;
 
 import jdk.test.lib.NetworkConfiguration;
@@ -106,6 +108,9 @@
             System.out.format("join %s @ %s%n", group.getHostAddress(), ni.getName());
             dc.join(group, ni);
 
+            System.out.format("set outgoing multicast interface to %s%n", ni.getName());
+            dc.setOption(IP_MULTICAST_IF, ni);
+
             // -- IP_MULTICAST_LOOP enabled --
 
             assertTrue(dc.getOption(IP_MULTICAST_LOOP), "IP_MULTICAST_LOOP not enabled");
--- a/test/jdk/java/util/regex/RegExTest.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/java/util/regex/RegExTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -35,7 +35,7 @@
  * 8027645 8035076 8039124 8035975 8074678 6854417 8143854 8147531 7071819
  * 8151481 4867170 7080302 6728861 6995635 6736245 4916384 6328855 6192895
  * 6345469 6988218 6693451 7006761 8140212 8143282 8158482 8176029 8184706
- * 8194667 8197462 8184692 8221431 8224789 8228352 8230829 8236034
+ * 8194667 8197462 8184692 8221431 8224789 8228352 8230829 8236034 8235812
  *
  * @library /test/lib
  * @library /lib/testlibrary/java/lang
@@ -57,7 +57,9 @@
 import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.Scanner;
 import java.util.function.Function;
@@ -186,6 +188,7 @@
         invalidGroupName();
         illegalRepetitionRange();
         surrogatePairWithCanonEq();
+        lineBreakWithQuantifier();
 
         if (failure) {
             throw new
@@ -5000,4 +5003,81 @@
         }
         report("surrogatePairWithCanonEq");
     }
+
+    // This test is for 8235812
+    private static void lineBreakWithQuantifier() {
+        // key:    pattern
+        // value:  lengths of input that must match the pattern
+        Map<String, List<Integer>> cases = Map.ofEntries(
+            Map.entry("\\R?",      List.of(0, 1)),
+            Map.entry("\\R*",      List.of(0, 1, 2, 3)),
+            Map.entry("\\R+",      List.of(1, 2, 3)),
+            Map.entry("\\R{0}",    List.of(0)),
+            Map.entry("\\R{1}",    List.of(1)),
+            Map.entry("\\R{2}",    List.of(2)),
+            Map.entry("\\R{3}",    List.of(3)),
+            Map.entry("\\R{0,}",   List.of(0, 1, 2, 3)),
+            Map.entry("\\R{1,}",   List.of(1, 2, 3)),
+            Map.entry("\\R{2,}",   List.of(2, 3)),
+            Map.entry("\\R{3,}",   List.of(3)),
+            Map.entry("\\R{0,0}",  List.of(0)),
+            Map.entry("\\R{0,1}",  List.of(0, 1)),
+            Map.entry("\\R{0,2}",  List.of(0, 1, 2)),
+            Map.entry("\\R{0,3}",  List.of(0, 1, 2, 3)),
+            Map.entry("\\R{1,1}",  List.of(1)),
+            Map.entry("\\R{1,2}",  List.of(1, 2)),
+            Map.entry("\\R{1,3}",  List.of(1, 2, 3)),
+            Map.entry("\\R{2,2}",  List.of(2)),
+            Map.entry("\\R{2,3}",  List.of(2, 3)),
+            Map.entry("\\R{3,3}",  List.of(3)),
+            Map.entry("\\R",       List.of(1)),
+            Map.entry("\\R\\R",    List.of(2)),
+            Map.entry("\\R\\R\\R", List.of(3))
+        );
+
+        // key:    length of input
+        // value:  all possible inputs of given length
+        Map<Integer, List<String>> inputs = new HashMap<>();
+        String[] Rs = { "\r\n", "\r", "\n",
+                        "\u000B", "\u000C", "\u0085", "\u2028", "\u2029" };
+        StringBuilder sb = new StringBuilder();
+        for (int len = 0; len <= 3; ++len) {
+            int[] idx = new int[len + 1];
+            do {
+                sb.setLength(0);
+                for (int j = 0; j < len; ++j)
+                    sb.append(Rs[idx[j]]);
+                inputs.computeIfAbsent(len, ArrayList::new).add(sb.toString());
+                idx[0]++;
+                for (int j = 0; j < len; ++j) {
+                    if (idx[j] < Rs.length)
+                        break;
+                    idx[j] = 0;
+                    idx[j+1]++;
+                }
+            } while (idx[len] == 0);
+        }
+
+        // exhaustive testing
+        for (String patStr : cases.keySet()) {
+            Pattern[] pats = patStr.endsWith("R")
+                ? new Pattern[] { Pattern.compile(patStr) }  // no quantifiers
+                : new Pattern[] { Pattern.compile(patStr),          // greedy
+                                  Pattern.compile(patStr + "?") };  // reluctant
+            Matcher m = pats[0].matcher("");
+            for (Pattern p : pats) {
+                m.usePattern(p);
+                for (int len : cases.get(patStr)) {
+                    for (String in : inputs.get(len)) {
+                        if (!m.reset(in).matches()) {
+                            failCount++;
+                            System.err.println("Expected to match '" +
+                                    in + "' =~ /" + p + "/");
+                        }
+                    }
+                }
+            }
+        }
+        report("lineBreakWithQuantifier");
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/naming/spi/DummyContextFactory.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.NoInitialContextException;
+import javax.naming.spi.InitialContextFactory;
+import javax.naming.spi.NamingManager;
+import java.util.Hashtable;
+
+public class DummyContextFactory implements InitialContextFactory {
+    static final String DUMMY_FACTORY = "DummyContextFactory";
+    static final String DUMMY_FACTORY2 = "DummyContextFactory2";
+    static final String MISSING_FACTORY = "NonExistant";
+    static int counter = 0;
+    ClassLoader origContextLoader = Thread.currentThread().getContextClassLoader();
+
+    public static void main(String[] s) throws Exception {
+        DummyContextFactory dcf = new DummyContextFactory();
+        dcf.runTest();
+    }
+
+    private void runTest() throws Exception {
+        final String classes = System.getProperty("url.dir", ".");
+        final URL curl = new File(classes).toURI().toURL();
+        URLClassLoader testLoader = new URLClassLoader(new URL[] {curl}, null);
+        WeakReference<URLClassLoader> weakRef = new WeakReference<>(testLoader);
+        Thread.currentThread().setContextClassLoader(testLoader);
+        Hashtable<String, String> env = new Hashtable<>();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, DUMMY_FACTORY);
+        testContextCalls(env);
+
+        // now test with another factory
+        Thread.currentThread().setContextClassLoader(testLoader);
+        env.put(Context.INITIAL_CONTEXT_FACTORY, DUMMY_FACTORY2);
+        testContextCalls(env);
+
+        // one count is derived from a default constructor call (ignored for test)
+        // class associated with this ClassLoader should have 2 counts
+        if (counter != 2) {
+            throw new RuntimeException("wrong count: " + counter);
+        }
+
+        // a test for handling non-existent classes
+        env.put(Context.INITIAL_CONTEXT_FACTORY, MISSING_FACTORY);
+        testBadContextCall(env);
+
+        // test that loader gets GC'ed
+        testLoader = null;
+        System.gc();
+        while (weakRef.get() != null) {
+            Thread.sleep(100);
+            System.gc();
+        }
+    }
+
+    private void testContextCalls(Hashtable<String, String> env) throws Exception {
+        // the context is returned here but it's the ContextFactory that
+        // we're mainly interested in. Hence the counter test.
+
+        // 1st call populates the WeakHashMap
+        // Uses URLClassLoader
+        Context cxt = NamingManager.getInitialContext(env);
+
+        // 2nd call uses cached factory
+        cxt = NamingManager.getInitialContext(env);
+
+        Thread.currentThread().setContextClassLoader(origContextLoader);
+
+        // 3rd call uses new factory
+        // AppClassLoader
+        cxt = NamingManager.getInitialContext(env);
+
+        // test with null TCCL
+        // this shouldn't increase the count since a null TCCL
+        // means we default to System ClassLoader in this case (AppClassLoader)
+        Thread.currentThread().setContextClassLoader(null);
+        cxt = NamingManager.getInitialContext(env);
+    }
+
+    private void testBadContextCall(Hashtable<String, String> env) throws Exception {
+        try {
+            Context cxt = NamingManager.getInitialContext(env);
+            throw new RuntimeException("Expected NoInitialContextException");
+        } catch (NoInitialContextException e) {
+            if (!(e.getCause() instanceof ClassNotFoundException)) {
+                throw new RuntimeException("unexpected cause", e.getCause());
+            }
+        }
+    }
+
+    public DummyContextFactory() {
+        System.out.println("New DummyContextFactory " + (++counter));
+        //new Throwable().printStackTrace(System.out);
+    }
+
+    @Override
+    public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+        return new DummyContext(environment);
+    }
+
+    public class DummyContext extends InitialContext {
+
+        private Hashtable env;
+
+        DummyContext(Hashtable env) throws NamingException {
+            this.env = env;
+        }
+
+        public Hashtable getEnvironment() {
+            return env;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/naming/spi/DummyContextFactory2.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import java.util.Hashtable;
+
+public class DummyContextFactory2 implements InitialContextFactory {
+    static int counter = 0;
+
+    public DummyContextFactory2() {
+        System.out.println("New DummyContextFactory2 " + (++counter));
+        //new Throwable().printStackTrace(System.out);
+    }
+
+    @Override
+    public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+        return new DummyContext(environment);
+    }
+
+    public class DummyContext extends InitialContext {
+
+        private Hashtable env;
+
+        DummyContext(Hashtable env) throws NamingException {
+            this.env = env;
+        }
+
+        public Hashtable getEnvironment() {
+            return env;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/naming/spi/FactoryCacheTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8223260
+ * @summary NamingManager should cache InitialContextFactory
+ * @library /test/lib
+ * @build jdk.test.lib.util.JarUtils jdk.test.lib.process.*
+ *        FactoryCacheTest
+ *        DummyContextFactory
+ *        DummyContextFactory2
+ * @run main FactoryCacheTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.util.JarUtils;
+
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.util.Arrays.asList;
+
+import static jdk.test.lib.Utils.TEST_CLASSES;
+
+public class FactoryCacheTest {
+
+    private static final Path SPIJAR = Path.of("testDir", "ContextFactory.jar");
+    private static final String SPIJAR_CP = SPIJAR.toAbsolutePath().toString();
+
+    public static void main(String[] args) throws Throwable {
+        List<String> argLine = new ArrayList<>();
+        argLine.add(JDKToolFinder.getJDKTool("java"));
+        argLine.addAll(asList(Utils.getTestJavaOpts()));
+        argLine.addAll(List.of("-cp", TEST_CLASSES));
+        argLine.addAll(List.of("-Durl.dir=" + TEST_CLASSES));
+        argLine.add("DummyContextFactory");
+
+        ProcessTools.executeCommand(argLine.stream()
+                .filter(t -> !t.isEmpty())
+                .toArray(String[]::new))
+                .shouldHaveExitValue(0);
+
+        // now test the ServiceLoader approach
+        setupService();
+        argLine = new ArrayList<>();
+        argLine.add(JDKToolFinder.getJDKTool("java"));
+        argLine.addAll(asList(Utils.getTestJavaOpts()));
+        argLine.addAll(List.of("-cp", SPIJAR_CP));
+        argLine.addAll(List.of("-Durl.dir=" + TEST_CLASSES));
+        argLine.add("DummyContextFactory");
+
+        ProcessTools.executeCommand(argLine.stream()
+                .filter(t -> !t.isEmpty())
+                .toArray(String[]::new))
+                .shouldHaveExitValue(0);
+    }
+
+    private static void setupService() throws Exception {
+        Path xdir = Path.of(TEST_CLASSES);
+        Path config = xdir.resolve(Path.of(TEST_CLASSES,"META-INF/services/javax.naming.spi.InitialContextFactory"));
+        Files.createDirectories(config.getParent());
+        Files.write(config, "DummyContextFactory".getBytes(), CREATE);
+        JarUtils.createJarFile(SPIJAR, xdir);
+    }
+}
--- a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java	Tue Feb 11 13:41:48 2020 +0530
@@ -29,8 +29,6 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-import jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin;
-
 import tests.Helper;
 import tests.JImageGenerator;
 import tests.JImageValidator;
@@ -62,32 +60,19 @@
 
         helper.generateDefaultModules();
 
-        // Test that generate-jli is enabled by default
-        Result result = JImageGenerator.getJLinkTask()
-                .modulePath(helper.defaultModulePath())
-                .output(helper.createNewImageDir("generate-jli"))
-                .addMods("java.base")
-                .call();
-
-        Path image = result.assertSuccess();
-
-        JImageValidator.validate(image.resolve("lib").resolve("modules"),
-                classFilesForSpecies(GenerateJLIClassesPlugin.defaultSpecies()),
-                List.of());
-
         // Check that --generate-jli-classes=@file works as intended
         Path baseFile = Files.createTempFile("base", "trace");
         String species = "LLLLLLLLLLLLLLLLLLL";
         String fileString = "[SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_" + species + " (salvaged)\n";
         Files.write(baseFile, fileString.getBytes(Charset.defaultCharset()));
-        result = JImageGenerator.getJLinkTask()
+        Result result = JImageGenerator.getJLinkTask()
                 .modulePath(helper.defaultModulePath())
                 .output(helper.createNewImageDir("generate-jli-file"))
                 .option("--generate-jli-classes=@" + baseFile.toString())
                 .addMods("java.base")
                 .call();
 
-        image = result.assertSuccess();
+        Path image = result.assertSuccess();
 
         JImageValidator.validate(image.resolve("lib").resolve("modules"),
                 classFilesForSpecies(List.of(species)), // species should be in the image
@@ -119,8 +104,7 @@
 
     private static List<String> classFilesForSpecies(Collection<String> species) {
         return species.stream()
-                .map(s -> "/java.base/java/lang/invoke/BoundMethodHandle$Species_"
-                        + GenerateJLIClassesPlugin.expandSignature(s) + ".class")
+                .map(s -> "/java.base/java/lang/invoke/BoundMethodHandle$Species_" + s + ".class")
                 .collect(Collectors.toList());
     }
 }
--- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Tue Feb 11 13:41:48 2020 +0530
@@ -32,6 +32,9 @@
  * @build javadoc.tester.*
  * @run main TestSearch
  */
+
+import java.util.Locale;
+
 import javadoc.tester.JavadocTester;
 
 public class TestSearch extends JavadocTester {
@@ -302,37 +305,85 @@
     }
 
     @Test
-    public void testJapaneseLocale() {
+    public void testDefaultJapaneseLocale() {
+        Locale prev = Locale.getDefault();
+        Locale.setDefault(Locale.forLanguageTag("ja-JP"));
+        try {
+            javadoc("-d", "out-jp-default",
+                    "-Xdoclint:none",
+                    "-sourcepath", testSrc,
+                    "-use",
+                    "pkg", "pkg1", "pkg2", "pkg3");
+            checkExit(Exit.OK);
+            checkOutput(Output.OUT, true,
+                    "\u30d1\u30c3\u30b1\u30fc\u30b8pkg\u306e\u30bd\u30fc\u30b9\u30fb\u30d5\u30a1" +
+                            "\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n",
+                    "\u30d1\u30c3\u30b1\u30fc\u30b8pkg1\u306e\u30bd\u30fc\u30b9\u30fb\u30d5\u30a1" +
+                            "\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n");
+            checkSearchJS();
+            checkSearchIndex(true);
+        } finally {
+            Locale.setDefault(prev);
+        }
+    }
+
+    @Test
+    public void testJapaneseLocaleOption() {
         javadoc("-locale", "ja_JP",
-                "-d", "out-jp",
+                "-d", "out-jp-option",
                 "-Xdoclint:none",
                 "-sourcepath", testSrc,
                 "-use",
                 "pkg", "pkg1", "pkg2", "pkg3");
         checkExit(Exit.OK);
         checkOutput(Output.OUT, true,
-                "\u30d1\u30c3\u30b1\u30fc\u30b8pkg\u306e\u30bd\u30fc\u30b9\u30fb\u30d5\u30a1" +
-                        "\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n",
-                "\u30d1\u30c3\u30b1\u30fc\u30b8pkg1\u306e\u30bd\u30fc\u30b9\u30fb\u30d5\u30a1" +
-                        "\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n");
+                "Loading source files for package pkg...\n",
+                "Loading source files for package pkg1...\n");
+        checkOutput("index.html", true,
+                "<span>\u30d1\u30c3\u30b1\u30fc\u30b8</span>");
         checkSearchJS();
         checkSearchIndex(true);
     }
 
     @Test
-    public void testChineseLocale() {
+    public void testDefaultChineseLocale() {
+        Locale prev = Locale.getDefault();
+        Locale.setDefault(Locale.forLanguageTag("zh-CN"));
+        try {
+            javadoc("-d", "out-cn-default",
+                    "-Xdoclint:none",
+                    "-sourcepath", testSrc,
+                    "-use",
+                    "pkg", "pkg1", "pkg2", "pkg3");
+            checkExit(Exit.OK);
+            checkOutput(Output.OUT, true,
+                    "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg\u7684\u6e90\u6587\u4ef6...\n",
+                    "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg1\u7684\u6e90\u6587\u4ef6...\n",
+                    "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg2\u7684\u6e90\u6587\u4ef6...\n",
+                    "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg3\u7684\u6e90\u6587\u4ef6...\n");
+            checkSearchJS();
+            checkSearchIndex(true);
+        } finally {
+            Locale.setDefault(prev);
+        }
+    }
+
+    @Test
+    public void testChineseLocaleOption() {
         javadoc("-locale", "zh_CN",
-                "-d", "out-cn",
+                "-d", "out-cn-option",
                 "-Xdoclint:none",
                 "-sourcepath", testSrc,
                 "-use",
                 "pkg", "pkg1", "pkg2", "pkg3");
         checkExit(Exit.OK);
         checkOutput(Output.OUT, true,
-                "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg\u7684\u6e90\u6587\u4ef6...\n",
-                "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg1\u7684\u6e90\u6587\u4ef6...\n",
-                "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg2\u7684\u6e90\u6587\u4ef6...\n",
-                "\u6b63\u5728\u52a0\u8f7d\u7a0b\u5e8f\u5305pkg3\u7684\u6e90\u6587\u4ef6...\n");
+                "Loading source files for package pkg...\n",
+                "Loading source files for package pkg1...\n",
+                "Loading source files for package pkg2...\n",
+                "Loading source files for package pkg3...\n");
+        checkOutput("index.html", true,
+                "<span>\u7a0b\u5e8f\u5305</span>");
         checkSearchJS();
         checkSearchIndex(true);
     }
--- a/test/langtools/jdk/javadoc/tool/testLocaleOption/TestLocaleOption.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/langtools/jdk/javadoc/tool/testLocaleOption/TestLocaleOption.java	Tue Feb 11 13:41:48 2020 +0530
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug     8222793
+ * @bug     8222793 8238437
  * @summary Javadoc tool ignores "-locale" param and uses default locale for
  *          all messages and texts
  * @library /tools/lib
@@ -42,6 +42,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.ResourceBundle;
 import java.nio.file.Files;
@@ -75,8 +76,10 @@
     private Path patchDir;
     private Path srcDir;
 
-    /** Locale for the generated resource files with uppercase values. */
-    private static final String LOCALE = "en_GB_ALLCAPS";
+    /**
+     * Locale for the generated resource files with uppercase values.
+     */
+    private static final Locale ALLCAPS = Locale.forLanguageTag("en-GB-ALLCAPS");
 
     TestLocaleOption() {
         super(System.err);
@@ -91,80 +94,107 @@
         srcDir = Path.of("src");
         tb.writeJavaFiles(srcDir,
                 "package p;\n"
-                + "public class HelloWorld {\n"
-                + "    public static void main(String... args) {\n"
-                + "        System.out.println(\"Hello World!\");\n"
-                + "    }\n"
-                + "}\n");
+                        + "public class HelloWorld {\n"
+                        + "    public static void main(String... args) {\n"
+                        + "        System.out.println(\"Hello World!\");\n"
+                        + "    }\n"
+                        + "}\n");
 
-        runTests(m -> new Object[] { Path.of(m.getName()) });
+        runTests(m -> new Object[]{Path.of(m.getName())});
     }
 
     @Test
-    public void testHelpDefault(Path base) {
-        String stdOut = javadoc(patchDir, "-help")
-                .writeAll()
-                .getOutput(Task.OutputKind.STDOUT);
-        checkContains(stdOut,
-                "Usage:\n"
-                +"    javadoc [options] [packagenames] [sourcefiles] [@files]");
+    public void testHelpDefault_US(Path base) {
+        testHelp(null, null);
+    }
+
+    @Test
+    public void testHelpDefault_ALLCAPS(Path base) {
+        testHelp(ALLCAPS, null);
     }
 
     @Test
     public void testHelpLocale(Path base) {
-        String stdOut = javadoc(patchDir, "-locale", LOCALE, "-help")
+        testHelp(null, ALLCAPS);
+    }
+
+    private void testHelp(Locale defaultLocale, Locale localeOption) {
+        String stdOut = javadoc(defaultLocale, localeOption, "-help")
                 .writeAll()
                 .getOutput(Task.OutputKind.STDOUT);
-        checkContains(stdOut,
-                "USAGE:\n"
-                +"    JAVADOC [OPTIONS] [PACKAGENAMES] [SOURCEFILES] [@FILES]");
+
+        if (Objects.equals(defaultLocale, ALLCAPS)) {
+            checkContains(stdOut,
+                    "USAGE:\n"
+                            + "    JAVADOC [OPTIONS] [PACKAGENAMES] [SOURCEFILES] [@FILES]");
+        } else {
+            checkContains(stdOut,
+                    "Usage:\n"
+                            + "    javadoc [options] [packagenames] [sourcefiles] [@files]");
+        }
     }
 
     @Test
-    public void testHelloWorldDefault(Path base) throws Exception {
+    public void testHelloWorldDefault_US(Path base) throws Exception {
+        testHelloWorld(base, null, null);
+    }
+
+    @Test
+    public void testHelloWorldDefault_ALLCAPS(Path base) throws Exception {
+        testHelloWorld(base, ALLCAPS, null);
+    }
+
+    @Test
+    public void testHelloWorldLocale(Path base) throws Exception {
+        testHelloWorld(base, null, ALLCAPS);
+    }
+
+    private void testHelloWorld(Path base, Locale defaultLocale, Locale localeOption) throws Exception {
         Path apiDir = base.resolve("api");
-        String stdOut = javadoc(patchDir,
+        String stdOut = javadoc(defaultLocale,
+                                localeOption,
                                 "-sourcepath", srcDir.toString(),
                                 "-d", apiDir.toString(),
                                 "p")
                 .writeAll()
                 .getOutput(Task.OutputKind.STDOUT);
 
-        checkContains(stdOut,
-                "Loading source files for package p...\n"
-                + "Constructing Javadoc information...");
+        // check console messages
+        if (Objects.equals(defaultLocale, ALLCAPS)) {
+            checkContains(stdOut,
+                    "LOADING SOURCE FILES FOR PACKAGE p...\n"
+                            + "CONSTRUCTING JAVADOC INFORMATION...");
+        } else {
+            checkContains(stdOut,
+                    "Loading source files for package p...\n"
+                            + "Constructing Javadoc information...");
+        }
 
+        // check generated files
         String hw = Files.readString(apiDir.resolve("p/HelloWorld.html"));
-        checkContains(hw,
-                "<h2>Method Summary</h2>",
-                "<th class=\"colFirst\" scope=\"col\">Modifier and Type</th>",
-                "<th class=\"colSecond\" scope=\"col\">Method</th>",
-                "<th class=\"colLast\" scope=\"col\">Description</th>");
+        Locale docLocale = localeOption != null ? localeOption : defaultLocale;
+        if (Objects.equals(docLocale, ALLCAPS)) {
+            checkContains(hw,
+                    "<h2>METHOD SUMMARY</h2>",
+                    "<th class=\"colFirst\" scope=\"col\">MODIFIER AND TYPE</th>",
+                    "<th class=\"colSecond\" scope=\"col\">METHOD</th>",
+                    "<th class=\"colLast\" scope=\"col\">DESCRIPTION</th>");
+        } else {
+            checkContains(hw,
+                    "<h2>Method Summary</h2>",
+                    "<th class=\"colFirst\" scope=\"col\">Modifier and Type</th>",
+                    "<th class=\"colSecond\" scope=\"col\">Method</th>",
+                    "<th class=\"colLast\" scope=\"col\">Description</th>");
+        }
     }
 
-    @Test
-    public void testHelloWorldLocale(Path base) throws Exception {
-        Path apiDir = base.resolve("api");
-        String stdOut = javadoc(patchDir,
-                                "-locale", LOCALE,
-                                "-sourcepath", srcDir.toString(),
-                                "-d", apiDir.toString(),
-                                "p")
-                .writeAll()
-                .getOutput(Task.OutputKind.STDOUT);
-
-        checkContains(stdOut,
-                "LOADING SOURCE FILES FOR PACKAGE p...\n"
-                + "CONSTRUCTING JAVADOC INFORMATION...");
-
-        String hw = Files.readString(apiDir.resolve("p/HelloWorld.html"));
-        checkContains(hw,
-                "<h2>METHOD SUMMARY</h2>",
-                "<th class=\"colFirst\" scope=\"col\">MODIFIER AND TYPE</th>",
-                "<th class=\"colSecond\" scope=\"col\">METHOD</th>",
-                "<th class=\"colLast\" scope=\"col\">DESCRIPTION</th>");
-    }
-
+    /**
+     * Generates a copy of a resource bundle, with the values converted to uppercase.
+     *
+     * @param dir  the root directory in which to write the bundle
+     * @param name the name of the bundle
+     * @throws Exception if an error occurs
+     */
     private void generateBundle(Path dir, String name) throws Exception {
         Module m = Main.class.getModule();
         ResourceBundle rb = ResourceBundle.getBundle(name, m);
@@ -175,7 +205,8 @@
             String value = rb.getString(key);
             p.put(key, value.toUpperCase(Locale.US));
         }
-        Path outPath = dir.resolve(name.replace(".", File.separator) + "_" + LOCALE + ".properties");
+        String localeSuffix = ALLCAPS.toString().replace("-", "_");
+        Path outPath = dir.resolve(name.replace(".", File.separator) + "_" + localeSuffix + ".properties");
         Files.createDirectories(outPath.getParent());
         try (Writer out = Files.newBufferedWriter(outPath)) {
             p.store(out, "Generated by TestLocaleOption");
@@ -183,10 +214,29 @@
         }
     }
 
-    private Task.Result javadoc(Path patchDir, String... args) {
+    /**
+     * Runs javadoc, with the specified arguments,
+     * optionally specifying the default locale and locale option
+     *
+     * @param defaultLocale the default locale for the VM, or null if not specified
+     * @param localeOption  the value for the locale option, or null if not specified
+     * @param args          additional command-line args
+     * @return the task result
+     */
+    private Task.Result javadoc(Locale defaultLocale, Locale localeOption, String... args) {
         List<String> options = new ArrayList<>();
         options.add("-J--patch-module=jdk.javadoc=" + patchDir);
+        if (defaultLocale != null) {
+            options.add("-J-Duser.language=" + defaultLocale.getLanguage());
+            options.add("-J-Duser.country=" + defaultLocale.getCountry());
+            options.add("-J-Duser.variant=" + defaultLocale.getVariant());
+        }
+        if (localeOption != null) {
+            options.addAll(List.of("-locale", localeOption.toString()));
+        }
         options.addAll(List.of(args));
+        System.err.println("Options: " + options);
+
         return new JavadocTask(tb, Task.Mode.EXEC)
                 .options(options)
                 .run();
--- a/test/micro/org/openjdk/bench/java/util/ImmutableColls.java	Sat Feb 08 18:48:42 2020 -0800
+++ b/test/micro/org/openjdk/bench/java/util/ImmutableColls.java	Tue Feb 11 13:41:48 2020 +0530
@@ -34,6 +34,9 @@
  */
 @State(Scope.Benchmark)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Fork(value = 3)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
 public class ImmutableColls {
 
     public static String[] STRINGS = {"hi", "all", "of", "you"};
@@ -217,6 +220,13 @@
                 fm4.containsValue("hi");
     }
 
+    @Benchmark
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public void getOrDefault(Blackhole bh) {
+        bh.consume(fm4.getOrDefault("hi", "test"));
+        bh.consume(fm4.getOrDefault("not_in_this_map", "test"));
+    }
+
     public int sizeOf(List<String> list) {
         return list.size();
     }