changeset 9998:88515137e73f icedtea-3.9.0pre02

Merge jdk8u172-b11
author andrew
date Mon, 27 Aug 2018 16:38:00 +0100
parents 6f7d65e42104 (current diff) 083a9d656210 (diff)
children a3f75e600099
files .hgtags src/os/bsd/vm/os_bsd.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp src/share/vm/memory/metaspace.cpp src/share/vm/memory/metaspace.hpp src/share/vm/opto/chaitin.cpp src/share/vm/opto/loopopts.cpp src/share/vm/opto/matcher.cpp src/share/vm/prims/jni.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/vm_operations.hpp src/share/vm/services/diagnosticCommand.cpp src/share/vm/services/diagnosticCommand.hpp test/TEST.groups
diffstat 33 files changed, 1293 insertions(+), 198 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sun Aug 19 04:29:57 2018 +0100
+++ b/.hgtags	Mon Aug 27 16:38:00 2018 +0100
@@ -1200,3 +1200,15 @@
 cb5711bf53d9278904c1ee63630a5c82189cb09a icedtea-3.8.0
 cb5711bf53d9278904c1ee63630a5c82189cb09a icedtea-3.9.0pre00
 0458118b5f190097099f2ea7b025cb2d5aeb0429 icedtea-3.9.0pre01
+23addae1b843a5027df6b4194f8c8de788da55ae jdk8u171-b11
+f299cf0b7baea1ae85f139f97adb9ab5499f402a jdk8u172-b00
+d10254debf7c1342416062bf1ba5258f16a8ce00 jdk8u172-b01
+653d9e0cd3f4023675c9eece7f0d563287f1d34f jdk8u172-b02
+771d9e1fbe1ae2ec4d5d937ebcbfd18e9c800098 jdk8u172-b03
+efd7a4e211e8fddf52053d4b033d8d307f356bc3 jdk8u172-b04
+4235fb1dceebde1192498ef388a32e56b1ed5a46 jdk8u172-b05
+68b234d5df6f01f3c677a114ecd6878c25f23f3c jdk8u172-b06
+a311a45523b19d59f77e76b0441a2085bb5355c8 jdk8u172-b07
+5c1f180db1650f0f33e6005c1366f0d68242f1ad jdk8u172-b08
+aafd1bb21e2636ba982d3eae162f5c635a1df03a jdk8u172-b09
+dcd3ace969fcde4eedaddba629647656289d4264 jdk8u172-b10
--- a/src/os/bsd/vm/os_bsd.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/os/bsd/vm/os_bsd.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1681,14 +1681,9 @@
 
   dlclose(handle);
 #elif defined(__APPLE__)
-  uint32_t count;
-  uint32_t i;
-
-  count = _dyld_image_count();
-  for (i = 1; i < count; i++) {
-    const char *name = _dyld_get_image_name(i);
-    intptr_t slide = _dyld_get_image_vmaddr_slide(i);
-    st->print_cr(PTR_FORMAT " \t%s", slide, name);
+  for (uint32_t i = 1; i < _dyld_image_count(); i++) {
+    st->print_cr(PTR_FORMAT " \t%s", _dyld_get_image_header(i),
+        _dyld_get_image_name(i));
   }
 #else
   st->print_cr("Error: Cannot print dynamic libraries.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/classLoaderStats.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/classLoaderStats.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+
+class ClassStatsClosure : public KlassClosure {
+public:
+  int _num_classes;
+
+  ClassStatsClosure() :
+    _num_classes(0) {
+  }
+
+  virtual void do_klass(Klass* k) {
+    _num_classes++;
+  }
+};
+
+
+void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
+  oop cl = cld->class_loader();
+  ClassLoaderStats* cls;
+
+  // The hashtable key is the ClassLoader oop since we want to account
+  // for "real" classes and anonymous classes together
+  ClassLoaderStats** cls_ptr = _stats->get(cl);
+  if (cls_ptr == NULL) {
+    cls = new ClassLoaderStats();
+    _stats->put(cl, cls);
+    _total_loaders++;
+  } else {
+    cls = *cls_ptr;
+  }
+
+  if (!cld->is_anonymous()) {
+    cls->_cld = cld;
+  }
+
+  cls->_class_loader = cl;
+  if (cl != NULL) {
+    cls->_parent = java_lang_ClassLoader::parent(cl);
+    addEmptyParents(cls->_parent);
+  }
+
+  ClassStatsClosure csc;
+  cld->classes_do(&csc);
+  if(cld->is_anonymous()) {
+    cls->_anon_classes_count += csc._num_classes;
+  } else {
+    cls->_classes_count = csc._num_classes;
+  }
+  _total_classes += csc._num_classes;
+
+  Metaspace* ms = cld->metaspace_or_null();
+  if (ms != NULL) {
+    if(cld->is_anonymous()) {
+      cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
+      cls->_anon_block_sz += ms->allocated_blocks_bytes();
+    } else {
+      cls->_chunk_sz = ms->allocated_chunks_bytes();
+      cls->_block_sz = ms->allocated_blocks_bytes();
+    }
+    _total_chunk_sz += ms->allocated_chunks_bytes();
+    _total_block_sz += ms->allocated_blocks_bytes();
+  }
+}
+
+
+// Handles the difference in pointer width on 32 and 64 bit platforms
+#ifdef _LP64
+  #define SPACE "%8s"
+#else
+  #define SPACE "%s"
+#endif
+
+
+bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
+  Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
+  Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
+
+  _out->print(INTPTR_FORMAT "  " INTPTR_FORMAT "  " INTPTR_FORMAT "  " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
+      p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
+      cls->_classes_count,
+      cls->_chunk_sz, cls->_block_sz);
+  if (class_loader_klass != NULL) {
+    _out->print("%s", class_loader_klass->external_name());
+  } else {
+    _out->print("<boot class loader>");
+  }
+  _out->cr();
+  if (cls->_anon_classes_count > 0) {
+    _out->print_cr(SPACE SPACE SPACE "                                    " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "   + unsafe anonymous classes",
+        "", "", "",
+        cls->_anon_classes_count,
+        cls->_anon_chunk_sz, cls->_anon_block_sz);
+  }
+  return true;
+}
+
+
+void ClassLoaderStatsClosure::print() {
+  _out->print_cr("ClassLoader" SPACE " Parent" SPACE "      CLD*" SPACE "       Classes   ChunkSz   BlockSz  Type", "", "", "");
+  _stats->iterate(this);
+  _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders);
+  _out->print(SPACE SPACE SPACE "                      ", "", "", "");
+  _out->print_cr(UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
+      _total_classes,
+      _total_chunk_sz,
+      _total_block_sz);
+  _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks");
+  _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)");
+}
+
+
+void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
+  while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
+    // This classloader has not loaded any classes
+    ClassLoaderStats** cls_ptr = _stats->get(cl);
+    if (cls_ptr == NULL) {
+      // It does not exist in our table - add it
+      ClassLoaderStats* cls = new ClassLoaderStats();
+      cls->_class_loader = cl;
+      cls->_parent = java_lang_ClassLoader::parent(cl);
+      _stats->put(cl, cls);
+      _total_loaders++;
+    }
+
+    cl = java_lang_ClassLoader::parent(cl);
+  }
+}
+
+
+void ClassLoaderStatsVMOperation::doit() {
+  ClassLoaderStatsClosure clsc (_out);
+  ClassLoaderDataGraph::cld_do(&clsc);
+  clsc.print();
+}
+
+
+void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) {
+  ClassLoaderStatsVMOperation op(output());
+  VMThread::execute(&op);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/classLoaderStats.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
+#define SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
+
+
+#include "classfile/classLoaderData.hpp"
+#include "oops/klass.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "runtime/vm_operations.hpp"
+#include "services/diagnosticCommand.hpp"
+#include "utilities/resourceHash.hpp"
+
+
+class ClassLoaderStatsDCmd : public DCmd {
+public:
+  ClassLoaderStatsDCmd(outputStream* output, bool heap) :
+    DCmd(output, heap) {
+  }
+
+  static const char* name() {
+    return "VM.classloader_stats";
+  }
+
+  static const char* description() {
+    return "Print statistics about all ClassLoaders.";
+  }
+
+  static const char* impact() {
+    return "Low";
+  }
+
+  virtual void execute(DCmdSource source, TRAPS);
+
+  static int num_arguments() {
+    return 0;
+  }
+
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+};
+
+
+class ClassLoaderStats : public ResourceObj {
+public:
+  ClassLoaderData*  _cld;
+  oop               _class_loader;
+  oop               _parent;
+
+  size_t            _chunk_sz;
+  size_t            _block_sz;
+  uintx             _classes_count;
+
+  size_t            _anon_chunk_sz;
+  size_t            _anon_block_sz;
+  uintx             _anon_classes_count;
+
+  ClassLoaderStats() :
+    _cld(0),
+    _class_loader(0),
+    _parent(0),
+    _chunk_sz(0),
+    _block_sz(0),
+    _classes_count(0),
+    _anon_block_sz(0),
+    _anon_chunk_sz(0),
+    _anon_classes_count(0) {
+  }
+};
+
+
+class ClassLoaderStatsClosure : public CLDClosure {
+protected:
+  static bool oop_equals(oop const& s1, oop const& s2) {
+    return s1 == s2;
+  }
+
+  static unsigned oop_hash(oop const& s1) {
+    unsigned hash = (unsigned)((uintptr_t)&s1);
+    return hash ^ (hash >> LogMinObjAlignment);
+  }
+
+  typedef ResourceHashtable<oop, ClassLoaderStats*,
+      ClassLoaderStatsClosure::oop_hash, ClassLoaderStatsClosure::oop_equals> StatsTable;
+
+  outputStream* _out;
+  StatsTable* _stats;
+  uintx   _total_loaders;
+  uintx   _total_classes;
+  size_t  _total_chunk_sz;
+  size_t  _total_block_sz;
+
+public:
+  ClassLoaderStatsClosure(outputStream* out) :
+    _out(out),
+    _total_loaders(0),
+    _total_block_sz(0),
+    _total_chunk_sz(0),
+    _total_classes(0),
+    _stats(new StatsTable()) {
+  }
+
+  virtual void do_cld(ClassLoaderData* cld);
+  virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls);
+  void print();
+
+private:
+  void addEmptyParents(oop cl);
+};
+
+
+class ClassLoaderStatsVMOperation : public VM_Operation {
+  outputStream* _out;
+
+public:
+  ClassLoaderStatsVMOperation(outputStream* out) :
+    _out(out) {
+  }
+
+  VMOp_Type type() const {
+    return VMOp_ClassLoaderStatsOperation;
+  }
+
+  void doit();
+};
+
+#endif // SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
--- a/src/share/vm/classfile/vmSymbols.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -573,6 +573,11 @@
   template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \
   template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \
   template(long_long_long_long_void_signature,         "(JJJJ)V")                                                 \
+  template(finalizer_histogram_klass,                  "java/lang/ref/FinalizerHistogram")                        \
+  template(void_finalizer_histogram_entry_array_signature,  "()[Ljava/lang/ref/FinalizerHistogram$Entry;")                        \
+  template(get_finalizer_histogram_name,               "getFinalizerHistogram")                                   \
+  template(finalizer_histogram_entry_name_field,       "className")                                               \
+  template(finalizer_histogram_entry_count_field,      "instanceCount")                                           \
                                                                                                                   \
   template(java_lang_management_MemoryPoolMXBean,      "java/lang/management/MemoryPoolMXBean")                   \
   template(java_lang_management_MemoryManagerMXBean,   "java/lang/management/MemoryManagerMXBean")                \
--- a/src/share/vm/memory/metaspace.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/memory/metaspace.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -154,7 +154,7 @@
 
   // Map a size to a list index assuming that there are lists
   // for special, small, medium, and humongous chunks.
-  static ChunkIndex list_index(size_t size);
+  ChunkIndex list_index(size_t size);
 
   // Remove the chunk from its freelist.  It is
   // expected to be on one of the _free_chunks[] lists.
@@ -531,9 +531,8 @@
 
   size_t free_bytes();
 
-  Metachunk* get_new_chunk(size_t word_size,
-                           size_t grow_chunks_by_words,
-                           size_t medium_chunk_bunch);
+  Metachunk* get_new_chunk(size_t chunk_word_size,
+                           size_t suggested_commit_granularity);
 
   bool expand_node_by(VirtualSpaceNode* node,
                       size_t min_words,
@@ -687,19 +686,27 @@
     MediumChunkMultiple = 4
   };
 
-  bool is_class() { return _mdtype == Metaspace::ClassType; }
+  static size_t specialized_chunk_size(bool is_class) { return is_class ? ClassSpecializedChunk : SpecializedChunk; }
+  static size_t small_chunk_size(bool is_class)       { return is_class ? ClassSmallChunk : SmallChunk; }
+  static size_t medium_chunk_size(bool is_class)      { return is_class ? ClassMediumChunk : MediumChunk; }
+
+  static size_t smallest_chunk_size(bool is_class)    { return specialized_chunk_size(is_class); }
 
   // Accessors
-  size_t specialized_chunk_size() { return (size_t) is_class() ? ClassSpecializedChunk : SpecializedChunk; }
-  size_t small_chunk_size()       { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; }
-  size_t medium_chunk_size()      { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; }
-  size_t medium_chunk_bunch()     { return medium_chunk_size() * MediumChunkMultiple; }
-
-  size_t smallest_chunk_size()  { return specialized_chunk_size(); }
+  bool is_class() const { return _mdtype == Metaspace::ClassType; }
+
+  size_t specialized_chunk_size() const { return specialized_chunk_size(is_class()); }
+  size_t small_chunk_size()       const { return small_chunk_size(is_class()); }
+  size_t medium_chunk_size()      const { return medium_chunk_size(is_class()); }
+
+  size_t smallest_chunk_size()    const { return smallest_chunk_size(is_class()); }
+
+  size_t medium_chunk_bunch()     const { return medium_chunk_size() * MediumChunkMultiple; }
 
   size_t allocated_blocks_words() const { return _allocated_blocks_words; }
   size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
   size_t allocated_chunks_words() const { return _allocated_chunks_words; }
+  size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; }
   size_t allocated_chunks_count() const { return _allocated_chunks_count; }
 
   bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
@@ -718,10 +725,13 @@
   // decremented for all the Metachunks in-use by this SpaceManager.
   void dec_total_from_size_metrics();
 
-  // Set the sizes for the initial chunks.
-  void get_initial_chunk_sizes(Metaspace::MetaspaceType type,
-                               size_t* chunk_word_size,
-                               size_t* class_chunk_word_size);
+  // Adjust the initial chunk size to match one of the fixed chunk list sizes,
+  // or return the unadjusted size if the requested size is humongous.
+  static size_t adjust_initial_chunk_size(size_t requested, bool is_class_space);
+  size_t adjust_initial_chunk_size(size_t requested) const;
+
+  // Get the initial chunks size for this metaspace type.
+  size_t get_initial_chunk_size(Metaspace::MetaspaceType type) const;
 
   size_t sum_capacity_in_chunks_in_use() const;
   size_t sum_used_in_chunks_in_use() const;
@@ -732,7 +742,7 @@
   size_t sum_count_in_chunks_in_use();
   size_t sum_count_in_chunks_in_use(ChunkIndex i);
 
-  Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words);
+  Metachunk* get_new_chunk(size_t chunk_word_size);
 
   // Block allocation and deallocation.
   // Allocates a block from the current chunk
@@ -1200,7 +1210,7 @@
 }
 
 size_t VirtualSpaceList::free_bytes() {
-  return virtual_space_list()->free_words_in_vs() * BytesPerWord;
+  return current_virtual_space()->free_words_in_vs() * BytesPerWord;
 }
 
 // Allocate another meta virtual space and add it to the list.
@@ -1319,12 +1329,10 @@
   return false;
 }
 
-Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
-                                           size_t grow_chunks_by_words,
-                                           size_t medium_chunk_bunch) {
+Metachunk* VirtualSpaceList::get_new_chunk(size_t chunk_word_size, size_t suggested_commit_granularity) {
 
   // Allocate a chunk out of the current virtual space.
-  Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
+  Metachunk* next = current_virtual_space()->get_chunk_vs(chunk_word_size);
 
   if (next != NULL) {
     return next;
@@ -1333,8 +1341,8 @@
   // The expand amount is currently only determined by the requested sizes
   // and not how much committed memory is left in the current virtual space.
 
-  size_t min_word_size       = align_size_up(grow_chunks_by_words, Metaspace::commit_alignment_words());
-  size_t preferred_word_size = align_size_up(medium_chunk_bunch,   Metaspace::commit_alignment_words());
+  size_t min_word_size       = align_size_up(chunk_word_size,              Metaspace::commit_alignment_words());
+  size_t preferred_word_size = align_size_up(suggested_commit_granularity, Metaspace::commit_alignment_words());
   if (min_word_size >= preferred_word_size) {
     // Can happen when humongous chunks are allocated.
     preferred_word_size = min_word_size;
@@ -1342,7 +1350,7 @@
 
   bool expanded = expand_by(min_word_size, preferred_word_size);
   if (expanded) {
-    next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
+    next = current_virtual_space()->get_chunk_vs(chunk_word_size);
     assert(next != NULL, "The allocation was expected to succeed after the expansion");
   }
 
@@ -1744,7 +1752,11 @@
   st->print_cr("Sum free chunk total " SIZE_FORMAT "  count " SIZE_FORMAT,
                 sum_free_chunks(), sum_free_chunks_count());
 }
+
 ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
+  assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex,
+         err_msg("Bad index: %d", (int)index));
+
   return &_free_chunks[index];
 }
 
@@ -1856,7 +1868,7 @@
   }
 
   assert((word_size <= chunk->word_size()) ||
-         list_index(chunk->word_size() == HumongousIndex),
+         (list_index(chunk->word_size()) == HumongousIndex),
          "Non-humongous variable sized chunk");
   if (TraceMetadataChunkAllocation) {
     size_t list_count;
@@ -1883,36 +1895,58 @@
 
 // SpaceManager methods
 
-void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type,
-                                           size_t* chunk_word_size,
-                                           size_t* class_chunk_word_size) {
-  switch (type) {
-  case Metaspace::BootMetaspaceType:
-    *chunk_word_size = Metaspace::first_chunk_word_size();
-    *class_chunk_word_size = Metaspace::first_class_chunk_word_size();
-    break;
-  case Metaspace::ROMetaspaceType:
-    *chunk_word_size = SharedReadOnlySize / wordSize;
-    *class_chunk_word_size = ClassSpecializedChunk;
-    break;
-  case Metaspace::ReadWriteMetaspaceType:
-    *chunk_word_size = SharedReadWriteSize / wordSize;
-    *class_chunk_word_size = ClassSpecializedChunk;
-    break;
-  case Metaspace::AnonymousMetaspaceType:
-  case Metaspace::ReflectionMetaspaceType:
-    *chunk_word_size = SpecializedChunk;
-    *class_chunk_word_size = ClassSpecializedChunk;
-    break;
-  default:
-    *chunk_word_size = SmallChunk;
-    *class_chunk_word_size = ClassSmallChunk;
-    break;
+size_t SpaceManager::adjust_initial_chunk_size(size_t requested, bool is_class_space) {
+  size_t chunk_sizes[] = {
+      specialized_chunk_size(is_class_space),
+      small_chunk_size(is_class_space),
+      medium_chunk_size(is_class_space)
+  };
+
+  // Adjust up to one of the fixed chunk sizes ...
+  for (size_t i = 0; i < ARRAY_SIZE(chunk_sizes); i++) {
+    if (requested <= chunk_sizes[i]) {
+      return chunk_sizes[i];
+    }
   }
-  assert(*chunk_word_size != 0 && *class_chunk_word_size != 0,
-    err_msg("Initial chunks sizes bad: data  " SIZE_FORMAT
-            " class " SIZE_FORMAT,
-            *chunk_word_size, *class_chunk_word_size));
+
+  // ... or return the size as a humongous chunk.
+  return requested;
+}
+
+size_t SpaceManager::adjust_initial_chunk_size(size_t requested) const {
+  return adjust_initial_chunk_size(requested, is_class());
+}
+
+size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const {
+  size_t requested;
+
+  if (is_class()) {
+    switch (type) {
+    case Metaspace::BootMetaspaceType:       requested = Metaspace::first_class_chunk_word_size(); break;
+    case Metaspace::ROMetaspaceType:         requested = ClassSpecializedChunk; break;
+    case Metaspace::ReadWriteMetaspaceType:  requested = ClassSpecializedChunk; break;
+    case Metaspace::AnonymousMetaspaceType:  requested = ClassSpecializedChunk; break;
+    case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break;
+    default:                                 requested = ClassSmallChunk; break;
+    }
+  } else {
+    switch (type) {
+    case Metaspace::BootMetaspaceType:       requested = Metaspace::first_chunk_word_size(); break;
+    case Metaspace::ROMetaspaceType:         requested = SharedReadOnlySize / wordSize; break;
+    case Metaspace::ReadWriteMetaspaceType:  requested = SharedReadWriteSize / wordSize; break;
+    case Metaspace::AnonymousMetaspaceType:  requested = SpecializedChunk; break;
+    case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break;
+    default:                                 requested = SmallChunk; break;
+    }
+  }
+
+  // Adjust to one of the fixed chunk sizes (unless humongous)
+  const size_t adjusted = adjust_initial_chunk_size(requested);
+
+  assert(adjusted != 0, err_msg("Incorrect initial chunk size. Requested: "
+         SIZE_FORMAT " adjusted: " SIZE_FORMAT, requested, adjusted));
+
+  return adjusted;
 }
 
 size_t SpaceManager::sum_free_in_chunks_in_use() const {
@@ -2102,8 +2136,8 @@
   }
 
   // Get another chunk out of the virtual space
-  size_t grow_chunks_by_words = calc_chunk_size(word_size);
-  Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
+  size_t chunk_word_size = calc_chunk_size(word_size);
+  Metachunk* next = get_new_chunk(chunk_word_size);
 
   MetaWord* mem = NULL;
 
@@ -2328,22 +2362,18 @@
 }
 
 ChunkIndex ChunkManager::list_index(size_t size) {
-  switch (size) {
-    case SpecializedChunk:
-      assert(SpecializedChunk == ClassSpecializedChunk,
-             "Need branch for ClassSpecializedChunk");
-      return SpecializedIndex;
-    case SmallChunk:
-    case ClassSmallChunk:
-      return SmallIndex;
-    case MediumChunk:
-    case ClassMediumChunk:
-      return MediumIndex;
-    default:
-      assert(size > MediumChunk || size > ClassMediumChunk,
-             "Not a humongous chunk");
-      return HumongousIndex;
+  if (free_chunks(SpecializedIndex)->size() == size) {
+    return SpecializedIndex;
+  }
+  if (free_chunks(SmallIndex)->size() == size) {
+    return SmallIndex;
   }
+  if (free_chunks(MediumIndex)->size() == size) {
+    return MediumIndex;
+  }
+
+  assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk");
+  return HumongousIndex;
 }
 
 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
@@ -2365,7 +2395,7 @@
 
   // Find the correct list and and set the current
   // chunk for that list.
-  ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
+  ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size());
 
   if (index != HumongousIndex) {
     retire_current_chunk();
@@ -2412,14 +2442,12 @@
   }
 }
 
-Metachunk* SpaceManager::get_new_chunk(size_t word_size,
-                                       size_t grow_chunks_by_words) {
+Metachunk* SpaceManager::get_new_chunk(size_t chunk_word_size) {
   // Get a chunk from the chunk freelist
-  Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
+  Metachunk* next = chunk_manager()->chunk_freelist_allocate(chunk_word_size);
 
   if (next == NULL) {
-    next = vs_list()->get_new_chunk(word_size,
-                                    grow_chunks_by_words,
+    next = vs_list()->get_new_chunk(chunk_word_size,
                                     medium_chunk_bunch());
   }
 
@@ -3125,7 +3153,7 @@
          err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
   assert(using_class_space(), "Must be using class space");
   _class_space_list = new VirtualSpaceList(rs);
-  _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
+  _chunk_manager_class = new ChunkManager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk);
 
   if (!_class_space_list->initialization_succeeded()) {
     vm_exit_during_initialization("Failed to setup compressed class space virtual space list.");
@@ -3326,66 +3354,62 @@
   MetaspaceGC::post_initialize();
 }
 
-Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
-                                               size_t chunk_word_size,
-                                               size_t chunk_bunch) {
+void Metaspace::initialize_first_chunk(MetaspaceType type, MetadataType mdtype) {
+  Metachunk* chunk = get_initialization_chunk(type, mdtype);
+  if (chunk != NULL) {
+    // Add to this manager's list of chunks in use and current_chunk().
+    get_space_manager(mdtype)->add_chunk(chunk, true);
+  }
+}
+
+Metachunk* Metaspace::get_initialization_chunk(MetaspaceType type, MetadataType mdtype) {
+  size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type);
+
   // Get a chunk from the chunk freelist
   Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size);
-  if (chunk != NULL) {
-    return chunk;
+
+  if (chunk == NULL) {
+    chunk = get_space_list(mdtype)->get_new_chunk(chunk_word_size,
+                                                  get_space_manager(mdtype)->medium_chunk_bunch());
+  }
+
+  // For dumping shared archive, report error if allocation has failed.
+  if (DumpSharedSpaces && chunk == NULL) {
+    report_insufficient_metaspace(MetaspaceAux::committed_bytes() + chunk_word_size * BytesPerWord);
   }
 
-  return get_space_list(mdtype)->get_new_chunk(chunk_word_size, chunk_word_size, chunk_bunch);
+  return chunk;
+}
+
+void Metaspace::verify_global_initialization() {
+  assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized");
+  assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized");
+
+  if (using_class_space()) {
+    assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized");
+    assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized");
+  }
 }
 
 void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
-
-  assert(space_list() != NULL,
-    "Metadata VirtualSpaceList has not been initialized");
-  assert(chunk_manager_metadata() != NULL,
-    "Metadata ChunkManager has not been initialized");
-
+  verify_global_initialization();
+
+  // Allocate SpaceManager for metadata objects.
   _vsm = new SpaceManager(NonClassType, lock);
-  if (_vsm == NULL) {
-    return;
-  }
-  size_t word_size;
-  size_t class_word_size;
-  vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
 
   if (using_class_space()) {
-  assert(class_space_list() != NULL,
-    "Class VirtualSpaceList has not been initialized");
-  assert(chunk_manager_class() != NULL,
-    "Class ChunkManager has not been initialized");
-
     // Allocate SpaceManager for classes.
     _class_vsm = new SpaceManager(ClassType, lock);
-    if (_class_vsm == NULL) {
-      return;
-    }
   }
 
   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
 
   // Allocate chunk for metadata objects
-  Metachunk* new_chunk = get_initialization_chunk(NonClassType,
-                                                  word_size,
-                                                  vsm()->medium_chunk_bunch());
-  assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
-  if (new_chunk != NULL) {
-    // Add to this manager's list of chunks in use and current_chunk().
-    vsm()->add_chunk(new_chunk, true);
-  }
+  initialize_first_chunk(type, NonClassType);
 
   // Allocate chunk for class metadata objects
   if (using_class_space()) {
-    Metachunk* class_chunk = get_initialization_chunk(ClassType,
-                                                      class_word_size,
-                                                      class_vsm()->medium_chunk_bunch());
-    if (class_chunk != NULL) {
-      class_vsm()->add_chunk(class_chunk, true);
-    }
+    initialize_first_chunk(type, ClassType);
   }
 
   _alloc_record_head = NULL;
@@ -3480,6 +3504,16 @@
   return capacity_words_slow(mdtype) * BytesPerWord;
 }
 
+size_t Metaspace::allocated_blocks_bytes() const {
+  return vsm()->allocated_blocks_bytes() +
+      (using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0);
+}
+
+size_t Metaspace::allocated_chunks_bytes() const {
+  return vsm()->allocated_chunks_bytes() +
+      (using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0);
+}
+
 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
   if (SafepointSynchronize::is_at_safepoint()) {
     if (DumpSharedSpaces && PrintSharedSpaces) {
@@ -3812,7 +3846,7 @@
     // vm_allocation_granularity aligned on Windows.
     size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord));
     large_size += (os::vm_page_size()/BytesPerWord);
-    vs_list->get_new_chunk(large_size, large_size, 0);
+    vs_list->get_new_chunk(large_size, 0);
   }
 
   static void test() {
@@ -3987,4 +4021,90 @@
   TestVirtualSpaceNodeTest::test();
   TestVirtualSpaceNodeTest::test_is_available();
 }
+
+// The following test is placed here instead of a gtest / unittest file
+// because the ChunkManager class is only available in this file.
+class SpaceManagerTest : AllStatic {
+  friend void SpaceManager_test_adjust_initial_chunk_size();
+
+  static void test_adjust_initial_chunk_size(bool is_class) {
+    const size_t smallest = SpaceManager::smallest_chunk_size(is_class);
+    const size_t normal   = SpaceManager::small_chunk_size(is_class);
+    const size_t medium   = SpaceManager::medium_chunk_size(is_class);
+
+#define test_adjust_initial_chunk_size(value, expected, is_class_value)          \
+    do {                                                                         \
+      size_t v = value;                                                          \
+      size_t e = expected;                                                       \
+      assert(SpaceManager::adjust_initial_chunk_size(v, (is_class_value)) == e,  \
+             err_msg("Expected: " SIZE_FORMAT " got: " SIZE_FORMAT, e, v));      \
+    } while (0)
+
+    // Smallest (specialized)
+    test_adjust_initial_chunk_size(1,            smallest, is_class);
+    test_adjust_initial_chunk_size(smallest - 1, smallest, is_class);
+    test_adjust_initial_chunk_size(smallest,     smallest, is_class);
+
+    // Small
+    test_adjust_initial_chunk_size(smallest + 1, normal, is_class);
+    test_adjust_initial_chunk_size(normal - 1,   normal, is_class);
+    test_adjust_initial_chunk_size(normal,       normal, is_class);
+
+    // Medium
+    test_adjust_initial_chunk_size(normal + 1, medium, is_class);
+    test_adjust_initial_chunk_size(medium - 1, medium, is_class);
+    test_adjust_initial_chunk_size(medium,     medium, is_class);
+
+    // Humongous
+    test_adjust_initial_chunk_size(medium + 1, medium + 1, is_class);
+
+#undef test_adjust_initial_chunk_size
+  }
+
+  static void test_adjust_initial_chunk_size() {
+    test_adjust_initial_chunk_size(false);
+    test_adjust_initial_chunk_size(true);
+  }
+};
+
+void SpaceManager_test_adjust_initial_chunk_size() {
+  SpaceManagerTest::test_adjust_initial_chunk_size();
+}
+
+// The following test is placed here instead of a gtest / unittest file
+// because the ChunkManager class is only available in this file.
+void ChunkManager_test_list_index() {
+  ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk);
+
+  // Test previous bug where a query for a humongous class metachunk,
+  // incorrectly matched the non-class medium metachunk size.
+  {
+    assert(MediumChunk > ClassMediumChunk, "Precondition for test");
+
+    ChunkIndex index = manager.list_index(MediumChunk);
+
+    assert(index == HumongousIndex,
+           err_msg("Requested size is larger than ClassMediumChunk,"
+           " so should return HumongousIndex. Got index: %d", (int)index));
+  }
+
+  // Check the specified sizes as well.
+  {
+    ChunkIndex index = manager.list_index(ClassSpecializedChunk);
+    assert(index == SpecializedIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
+  }
+  {
+    ChunkIndex index = manager.list_index(ClassSmallChunk);
+    assert(index == SmallIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
+  }
+  {
+    ChunkIndex index = manager.list_index(ClassMediumChunk);
+    assert(index == MediumIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
+  }
+  {
+    ChunkIndex index = manager.list_index(ClassMediumChunk + 1);
+    assert(index == HumongousIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
+  }
+}
+
 #endif
--- a/src/share/vm/memory/metaspace.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/memory/metaspace.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,14 +104,15 @@
   };
 
  private:
+  static void verify_global_initialization();
+
   void initialize(Mutex* lock, MetaspaceType type);
 
-  // Get the first chunk for a Metaspace.  Used for
+  // Initialize the first chunk for a Metaspace.  Used for
   // special cases such as the boot class loader, reflection
   // class loader and anonymous class loader.
-  Metachunk* get_initialization_chunk(MetadataType mdtype,
-                                      size_t chunk_word_size,
-                                      size_t chunk_bunch);
+  void initialize_first_chunk(MetaspaceType type, MetadataType mdtype);
+  Metachunk* get_initialization_chunk(MetaspaceType type, MetadataType mdtype);
 
   // Align up the word size to the allocation word size
   static size_t align_word_size_up(size_t);
@@ -138,6 +139,10 @@
 
   SpaceManager* _class_vsm;
   SpaceManager* class_vsm() const { return _class_vsm; }
+  SpaceManager* get_space_manager(MetadataType mdtype) {
+    assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
+    return mdtype == ClassType ? class_vsm() : vsm();
+  }
 
   // Allocate space for metadata of type mdtype. This is space
   // within a Metachunk and is used by
@@ -227,6 +232,9 @@
   size_t used_bytes_slow(MetadataType mdtype) const;
   size_t capacity_bytes_slow(MetadataType mdtype) const;
 
+  size_t allocated_blocks_bytes() const;
+  size_t allocated_chunks_bytes() const;
+
   static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
                             bool read_only, MetaspaceObj::Type type, TRAPS);
   void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
--- a/src/share/vm/memory/resourceArea.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/memory/resourceArea.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,15 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.inline.hpp"
+#include "services/memTracker.hpp"
+
+void ResourceArea::bias_to(MEMFLAGS new_flags) {
+  if (new_flags != _flags) {
+    MemTracker::record_arena_free(_flags);
+    MemTracker::record_new_arena(new_flags);
+    _flags = new_flags;
+  }
+}
 
 //------------------------------ResourceMark-----------------------------------
 debug_only(int ResourceArea::_warned;)      // to suppress multiple warnings
--- a/src/share/vm/memory/resourceArea.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/memory/resourceArea.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,11 +49,11 @@
   debug_only(static int _warned;)       // to suppress multiple warnings
 
 public:
-  ResourceArea() : Arena(mtThread) {
+  ResourceArea(MEMFLAGS flags = mtThread) : Arena(flags) {
     debug_only(_nesting = 0;)
   }
 
-  ResourceArea(size_t init_size) : Arena(mtThread, init_size) {
+  ResourceArea(size_t init_size, MEMFLAGS flags = mtThread) : Arena(flags, init_size) {
     debug_only(_nesting = 0;);
   }
 
@@ -70,7 +70,11 @@
     return (char*)Amalloc(size, alloc_failmode);
   }
 
-  debug_only(int nesting() const { return _nesting; });
+  // Bias this resource area to specific memory type
+  // (by default, ResourceArea is tagged as mtThread, per-thread general purpose storage)
+  void bias_to(MEMFLAGS flags);
+
+  debug_only(int nesting() const { return _nesting; })
 };
 
 
--- a/src/share/vm/opto/chaitin.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/opto/chaitin.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -338,8 +338,8 @@
   _alternate = 0;
   _matcher._allocation_started = true;
 
-  ResourceArea split_arena;     // Arena for Split local resources
-  ResourceArea live_arena;      // Arena for liveness & IFG info
+  ResourceArea split_arena(mtCompiler);     // Arena for Split local resources
+  ResourceArea live_arena(mtCompiler);      // Arena for liveness & IFG info
   ResourceMark rm(&live_arena);
 
   // Need live-ness for the IFG; need the IFG for coalescing.  If the
--- a/src/share/vm/opto/loopopts.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/opto/loopopts.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/share/vm/opto/matcher.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/opto/matcher.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -81,7 +81,7 @@
   _register_save_type(register_save_type),
   _ruleName(ruleName),
   _allocation_started(false),
-  _states_arena(Chunk::medium_size),
+  _states_arena(Chunk::medium_size, mtCompiler),
   _visited(&_states_arena),
   _shared(&_states_arena),
   _dontcare(&_states_arena) {
--- a/src/share/vm/prims/jni.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/prims/jni.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -5095,6 +5095,7 @@
 void TestReserveMemorySpecial_test();
 void TestVirtualSpace_test();
 void TestMetaspaceAux_test();
+void SpaceManager_test_adjust_initial_chunk_size();
 void TestMetachunk_test();
 void TestVirtualSpaceNode_test();
 void TestNewSize_test();
@@ -5107,6 +5108,7 @@
 void TestBufferingOopClosure_test();
 void TestCodeCacheRemSet_test();
 void FreeRegionList_test();
+void ChunkManager_test_list_index();
 #endif
 
 void execute_internal_vm_tests() {
@@ -5139,6 +5141,8 @@
     run_unit_test(TestOldFreeSpaceCalculation_test());
     run_unit_test(TestG1BiasedArray_test());
     run_unit_test(HeapRegionRemSet::test_prt());
+    run_unit_test(SpaceManager_test_adjust_initial_chunk_size());
+    run_unit_test(ChunkManager_test_list_index());
     run_unit_test(TestBufferingOopClosure_test());
     run_unit_test(TestCodeCacheRemSet_test());
     if (UseG1GC) {
--- a/src/share/vm/runtime/thread.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/runtime/thread.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -3242,6 +3242,9 @@
   _scanned_nmethod = NULL;
   _compiler = NULL;
 
+  // Compiler uses resource area for compilation, let's bias it to mtCompiler
+  resource_area()->bias_to(mtCompiler);
+
 #ifndef PRODUCT
   _ideal_graph_printer = NULL;
 #endif
--- a/src/share/vm/runtime/vm_operations.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/runtime/vm_operations.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -97,6 +97,7 @@
   template(LinuxDllLoad)                          \
   template(RotateGCLog)                           \
   template(WhiteBoxOperation)                     \
+  template(ClassLoaderStatsOperation)             \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
--- a/src/share/vm/services/diagnosticCommand.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/diagnosticCommand.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,14 +23,17 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderStats.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
 #include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
 #include "services/diagnosticArgument.hpp"
 #include "services/diagnosticCommand.hpp"
 #include "services/diagnosticFramework.hpp"
 #include "services/heapDumper.hpp"
 #include "services/management.hpp"
 #include "utilities/macros.hpp"
+#include "oops/objArrayOop.hpp"
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
@@ -46,9 +49,12 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false));
 #if INCLUDE_SERVICES // Heap dumping/inspection supported
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
@@ -56,6 +62,7 @@
 #endif // INCLUDE_SERVICES
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
 
   // Enhanced JMX Agent Support
   // These commands won't be exported via the DiagnosticCommandMBean until an
@@ -273,6 +280,60 @@
                          vmSymbols::void_method_signature(), CHECK);
 }
 
+void HeapInfoDCmd::execute(DCmdSource source, TRAPS) {
+  Universe::heap()->print_on(output());
+}
+
+void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) {
+  ResourceMark rm;
+
+
+  Klass* k = SystemDictionary::resolve_or_null(
+    vmSymbols::finalizer_histogram_klass(), THREAD);
+  assert(k != NULL, "FinalizerHistogram class is not accessible");
+
+  instanceKlassHandle klass(THREAD, k);
+  JavaValue result(T_ARRAY);
+
+  // We are calling lang.ref.FinalizerHistogram.getFinalizerHistogram() method
+  // and expect it to return array of FinalizerHistogramEntry as Object[]
+
+  JavaCalls::call_static(&result, klass,
+                         vmSymbols::get_finalizer_histogram_name(),
+                         vmSymbols::void_finalizer_histogram_entry_array_signature(), CHECK);
+
+  objArrayOop result_oop = (objArrayOop) result.get_jobject();
+  if (result_oop->length() == 0) {
+    output()->print_cr("No instances waiting for finalization found");
+    return;
+  }
+
+  oop foop = result_oop->obj_at(0);
+  InstanceKlass* ik = InstanceKlass::cast(foop->klass());
+
+  fieldDescriptor count_fd, name_fd;
+
+  Klass* count_res = ik->find_field(
+    vmSymbols::finalizer_histogram_entry_count_field(), vmSymbols::int_signature(), &count_fd);
+
+  Klass* name_res = ik->find_field(
+    vmSymbols::finalizer_histogram_entry_name_field(), vmSymbols::string_signature(), &name_fd);
+
+  assert(count_res != NULL && name_res != NULL, "Unexpected layout of FinalizerHistogramEntry");
+
+  output()->print_cr("Unreachable instances waiting for finalization");
+  output()->print_cr("#instances  class name");
+  output()->print_cr("-----------------------");
+
+  for (int i = 0; i < result_oop->length(); ++i) {
+    oop element_oop = result_oop->obj_at(i);
+    oop str_oop = element_oop->obj_field(name_fd.offset());
+    char *name = java_lang_String::as_utf8_string(str_oop);
+    int count = element_oop->int_field(count_fd.offset());
+    output()->print_cr("%10d  %s", count, name);
+  }
+}
+
 #if INCLUDE_SERVICES // Heap dumping/inspection supported
 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
                            DCmdWithParser(output, heap),
@@ -619,8 +680,7 @@
 }
 
 JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) :
-  DCmd(output, heap_allocated)
-{
+  DCmd(output, heap_allocated) {
   // do nothing
 }
 
@@ -641,7 +701,6 @@
     JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK);
 }
 
-
 void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) {
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
@@ -659,6 +718,16 @@
     JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
 }
 
+VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) :
+  DCmd(output, heap_allocated) {
+  // do nothing
+}
+
+void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) {
+  os::print_dll_info(output());
+  output()->cr();
+}
+
 void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) {
   if (UseGCLogFileRotation) {
     VM_RotateGCLog rotateop(output());
--- a/src/share/vm/services/diagnosticCommand.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/diagnosticCommand.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,29 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class VMDynamicLibrariesDCmd : public DCmd {
+public:
+  VMDynamicLibrariesDCmd(outputStream* output, bool heap);
+  static const char* name() {
+    return "VM.dynlibs";
+  }
+  static const char* description() {
+    return "Print loaded dynamic libraries.";
+  }
+  static const char* impact() {
+    return "Low";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() {
+    return 0;
+  };
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 class VMUptimeDCmd : public DCmdWithParser {
 protected:
   DCmdArgument<bool> _date;
@@ -176,6 +199,46 @@
     virtual void execute(DCmdSource source, TRAPS);
 };
 
+class HeapInfoDCmd : public DCmd {
+public:
+  HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
+  static const char* name() { return "GC.heap_info"; }
+  static const char* description() {
+    return "Provide generic Java heap information.";
+  }
+  static const char* impact() {
+    return "Medium";
+  }
+  static int num_arguments() { return 0; }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+      "monitor", NULL};
+      return p;
+  }
+
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+class FinalizerInfoDCmd : public DCmd {
+public:
+  FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
+  static const char* name() { return "GC.finalizer_info"; }
+  static const char* description() {
+    return "Provide information about Java finalization queue.";
+  }
+  static const char* impact() {
+    return "Medium";
+  }
+  static int num_arguments() { return 0; }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+      "monitor", NULL};
+      return p;
+  }
+
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 #if INCLUDE_SERVICES   // Heap dumping supported
 // See also: dump_heap in attachListener.cpp
 class HeapDumpDCmd : public DCmdWithParser {
--- a/src/share/vm/services/mallocSiteTable.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/mallocSiteTable.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -97,7 +97,7 @@
 
   // Instantiate hash entry for hashtable entry allocation callsite
   MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site)
-    MallocSiteHashtableEntry(*stack);
+    MallocSiteHashtableEntry(*stack, mtNMT);
 
   // Add the allocation site to hashtable.
   int index = hash_to_index(stack->hash());
@@ -134,7 +134,8 @@
  *  Under any of above circumstances, caller should handle the situation.
  */
 MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx,
-  size_t* pos_idx) {
+  size_t* pos_idx, MEMFLAGS flags) {
+  assert(flags != mtNone, "Should have a real memory type");
   int index = hash_to_index(key.hash());
   assert(index >= 0, "Negative index");
   *bucket_idx = (size_t)index;
@@ -142,7 +143,7 @@
 
   // First entry for this hash bucket
   if (_table[index] == NULL) {
-    MallocSiteHashtableEntry* entry = new_entry(key);
+    MallocSiteHashtableEntry* entry = new_entry(key, flags);
     // OOM check
     if (entry == NULL) return NULL;
 
@@ -157,13 +158,12 @@
   MallocSiteHashtableEntry* head = _table[index];
   while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) {
     MallocSite* site = head->data();
-    if (site->equals(key)) {
-      // found matched entry
+    if (site->flags() == flags && site->equals(key)) {
       return head->data();
     }
 
     if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) {
-      MallocSiteHashtableEntry* entry = new_entry(key);
+      MallocSiteHashtableEntry* entry = new_entry(key, flags);
       // OOM check
       if (entry == NULL) return NULL;
       if (head->atomic_insert(entry)) {
@@ -192,10 +192,10 @@
 // Allocates MallocSiteHashtableEntry object. Special call stack
 // (pre-installed allocation site) has to be used to avoid infinite
 // recursion.
-MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key) {
+MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key, MEMFLAGS flags) {
   void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT,
     *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL);
-  return ::new (p) MallocSiteHashtableEntry(key);
+  return ::new (p) MallocSiteHashtableEntry(key, flags);
 }
 
 void MallocSiteTable::reset() {
--- a/src/share/vm/services/mallocSiteTable.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/mallocSiteTable.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,12 +37,16 @@
 // MallocSite represents a code path that eventually calls
 // os::malloc() to allocate memory
 class MallocSite : public AllocationSite<MemoryCounter> {
+ private:
+  MEMFLAGS _flags;
+
  public:
   MallocSite() :
-    AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK) { }
+    AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK), _flags(mtNone) {}
 
-  MallocSite(const NativeCallStack& stack) :
-    AllocationSite<MemoryCounter>(stack) { }
+  MallocSite(const NativeCallStack& stack, MEMFLAGS flags) :
+    AllocationSite<MemoryCounter>(stack), _flags(flags) {}
+
 
   void allocate(size_t size)      { data()->allocate(size);   }
   void deallocate(size_t size)    { data()->deallocate(size); }
@@ -51,6 +55,7 @@
   size_t size()  const { return peek()->size(); }
   // The number of calls were made
   size_t count() const { return peek()->count(); }
+  MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
 };
 
 // Malloc site hashtable entry
@@ -62,8 +67,10 @@
  public:
   MallocSiteHashtableEntry() : _next(NULL) { }
 
-  MallocSiteHashtableEntry(NativeCallStack stack):
-    _malloc_site(stack), _next(NULL) { }
+  MallocSiteHashtableEntry(NativeCallStack stack, MEMFLAGS flags):
+    _malloc_site(stack, flags), _next(NULL) {
+    assert(flags != mtNone, "Expect a real memory type");
+  }
 
   inline const MallocSiteHashtableEntry* next() const {
     return _next;
@@ -198,11 +205,11 @@
   //  1. out of memory
   //  2. overflow hash bucket
   static inline bool allocation_at(const NativeCallStack& stack, size_t size,
-    size_t* bucket_idx, size_t* pos_idx) {
+    size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) {
     AccessLock locker(&_access_count);
     if (locker.sharedLock()) {
       NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);)
-      MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx);
+      MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx, flags);
       if (site != NULL) site->allocate(size);
       return site != NULL;
     }
@@ -228,13 +235,13 @@
   static bool walk_malloc_site(MallocSiteWalker* walker);
 
  private:
-  static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key);
+  static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key, MEMFLAGS flags);
   static void reset();
 
   // Delete a bucket linked list
   static void delete_linked_list(MallocSiteHashtableEntry* head);
 
-  static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx);
+  static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags);
   static MallocSite* malloc_site(size_t bucket_idx, size_t pos_idx);
   static bool walk(MallocSiteWalker* walker);
 
--- a/src/share/vm/services/mallocTracker.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/mallocTracker.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,8 @@
 }
 
 bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size,
-  size_t* bucket_idx, size_t* pos_idx) const {
-  bool ret =  MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx);
+  size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const {
+  bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags);
 
   // Something went wrong, could be OOM or overflow malloc site table.
   // We want to keep tracking data under OOM circumstance, so transition to
--- a/src/share/vm/services/mallocTracker.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/mallocTracker.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -268,7 +268,7 @@
     if (level == NMT_detail) {
       size_t bucket_idx;
       size_t pos_idx;
-      if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
+      if (record_malloc_site(stack, size, &bucket_idx, &pos_idx, flags)) {
         assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
         assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
         _bucket_idx = bucket_idx;
@@ -292,7 +292,7 @@
     _size = size;
   }
   bool record_malloc_site(const NativeCallStack& stack, size_t size,
-    size_t* bucket_idx, size_t* pos_idx) const;
+    size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const;
 };
 
 
--- a/src/share/vm/services/memBaseline.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/memBaseline.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,15 @@
   return s1.call_stack()->compare(*s2.call_stack());
 }
 
+// Sort into allocation site addresses and memory type order for baseline comparison
+int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) {
+  int res = compare_malloc_site(s1, s2);
+  if (res == 0) {
+    res = (int)(s1.flags() - s2.flags());
+  }
+
+  return res;
+}
 
 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,
   const VirtualMemoryAllocationSite& s2) {
@@ -225,6 +234,9 @@
     case by_site:
       malloc_sites_to_allocation_site_order();
       break;
+    case by_site_and_type:
+      malloc_sites_to_allocation_site_and_type_order();
+      break;
     case by_address:
     default:
       ShouldNotReachHere();
@@ -263,7 +275,7 @@
 }
 
 void MemBaseline::malloc_sites_to_allocation_site_order() {
-  if (_malloc_sites_order != by_site) {
+  if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) {
     SortedLinkedList<MallocSite, compare_malloc_site> tmp;
     // Add malloc sites to sorted linked list to sort into site (address) order
     tmp.move(&_malloc_sites);
@@ -273,6 +285,17 @@
   }
 }
 
+void MemBaseline::malloc_sites_to_allocation_site_and_type_order() {
+  if (_malloc_sites_order != by_site_and_type) {
+    SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp;
+    // Add malloc sites to sorted linked list to sort into site (address) order
+    tmp.move(&_malloc_sites);
+    _malloc_sites.set_head(tmp.head());
+    tmp.set_head(NULL);
+    _malloc_sites_order = by_site_and_type;
+  }
+}
+
 void MemBaseline::virtual_memory_sites_to_size_order() {
   if (_virtual_memory_sites_order != by_size) {
     SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
--- a/src/share/vm/services/memBaseline.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/memBaseline.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,9 +55,10 @@
   };
 
   enum SortingOrder {
-    by_address,   // by memory address
-    by_size,      // by memory size
-    by_site       // by call site where the memory is allocated from
+    by_address,      // by memory address
+    by_size,         // by memory size
+    by_site,         // by call site where the memory is allocated from
+    by_site_and_type // by call site and memory type
   };
 
  private:
@@ -188,6 +189,8 @@
   void malloc_sites_to_size_order();
   // Sort allocation sites in call site address order
   void malloc_sites_to_allocation_site_order();
+  // Sort allocation sites in call site address and memory type order
+  void malloc_sites_to_allocation_site_and_type_order();
 
   // Sort allocation sites in reserved size order
   void virtual_memory_sites_to_size_order();
--- a/src/share/vm/services/memReporter.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/memReporter.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,11 +43,16 @@
     amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
 }
 
-void MemReporterBase::print_malloc(size_t amount, size_t count) const {
+void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) const {
   const char* scale = current_scale();
   outputStream* out = output();
-  out->print("(malloc=" SIZE_FORMAT "%s",
-    amount_in_current_scale(amount), scale);
+  if (flag != mtNone) {
+    out->print("(malloc=" SIZE_FORMAT "%s type=%s",
+      amount_in_current_scale(amount), scale, NMTUtil::flag_to_name(flag));
+  } else {
+    out->print("(malloc=" SIZE_FORMAT "%s",
+      amount_in_current_scale(amount), scale);
+  }
 
   if (count > 0) {
     out->print(" #" SIZE_FORMAT "", count);
@@ -200,7 +205,10 @@
     const NativeCallStack* stack = malloc_site->call_stack();
     stack->print_on(out);
     out->print("%29s", " ");
-    print_malloc(malloc_site->size(), malloc_site->count());
+    MEMFLAGS flag = malloc_site->flags();
+    assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone,
+      "Must have a valid memory type");
+    print_malloc(malloc_site->size(), malloc_site->count(),flag);
     out->print_cr("\n");
   }
 }
@@ -304,11 +312,16 @@
 }
 
 void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t current_count,
-    size_t early_amount, size_t early_count) const {
+    size_t early_amount, size_t early_count, MEMFLAGS flags) const {
   const char* scale = current_scale();
   outputStream* out = output();
 
   out->print("malloc=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
+  // Report type only if it is valid
+  if (flags != mtNone) {
+    out->print(" type=%s", NMTUtil::flag_to_name(flags));
+  }
+
   long amount_diff = diff_in_current_scale(current_amount, early_amount);
   if (amount_diff != 0) {
     out->print(" %+ld%s", amount_diff, scale);
@@ -437,7 +450,7 @@
         diff_in_current_scale(current_malloc_amount, early_malloc_amount) != 0) {
       out->print("%28s(", " ");
       print_malloc_diff(current_malloc_amount, (flag == mtChunk) ? 0 : current_malloc->malloc_count(),
-        early_malloc_amount, early_malloc->malloc_count());
+        early_malloc_amount, early_malloc->malloc_count(), mtNone);
       out->print_cr(")");
     }
 
@@ -485,8 +498,8 @@
 }
 
 void MemDetailDiffReporter::diff_malloc_sites() const {
-  MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site);
-  MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site);
+  MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site_and_type);
+  MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site_and_type);
 
   const MallocSite* early_site   = early_itr.next();
   const MallocSite* current_site = current_itr.next();
@@ -549,22 +562,23 @@
 
 void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const {
   diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(),
-    0, 0);
+    0, 0, malloc_site->flags());
 }
 
 void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const {
   diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(),
-    malloc_site->count());
+    malloc_site->count(), malloc_site->flags());
 }
 
 void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early,
   const MallocSite* current)  const {
+  assert(early->flags() == current->flags(), "Must be the same memory type");
   diff_malloc_site(current->call_stack(), current->size(), current->count(),
-    early->size(), early->count());
+    early->size(), early->count(), early->flags());
 }
 
 void MemDetailDiffReporter::diff_malloc_site(const NativeCallStack* stack, size_t current_size,
-  size_t current_count, size_t early_size, size_t early_count) const {
+  size_t current_count, size_t early_size, size_t early_count, MEMFLAGS flags) const {
   outputStream* out = output();
 
   assert(stack != NULL, "NULL stack");
@@ -576,7 +590,7 @@
   stack->print_on(out);
   out->print("%28s (", " ");
   print_malloc_diff(current_size, current_count,
-    early_size, early_count);
+    early_size, early_count, flags);
 
   out->print_cr(")\n");
 }
--- a/src/share/vm/services/memReporter.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/services/memReporter.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,7 +76,7 @@
 
   // Print summary total, malloc and virtual memory
   void print_total(size_t reserved, size_t committed) const;
-  void print_malloc(size_t amount, size_t count) const;
+  void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const;
   void print_virtual_memory(size_t reserved, size_t committed) const;
 
   void print_malloc_line(size_t amount, size_t count) const;
@@ -174,7 +174,7 @@
 
  protected:
   void print_malloc_diff(size_t current_amount, size_t current_count,
-    size_t early_amount, size_t early_count) const;
+    size_t early_amount, size_t early_count, MEMFLAGS flags) const;
   void print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
     size_t early_reserved, size_t early_committed) const;
   void print_arena_diff(size_t current_amount, size_t current_count,
@@ -216,7 +216,7 @@
                                 const VirtualMemoryAllocationSite* current)  const;
 
   void diff_malloc_site(const NativeCallStack* stack, size_t current_size,
-    size_t currrent_count, size_t early_size, size_t early_count) const;
+    size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const;
   void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
     size_t current_committed, size_t early_reserved, size_t early_committed) const;
 };
--- a/src/share/vm/utilities/debug.cpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/utilities/debug.cpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -315,6 +315,14 @@
   }
 }
 
+void report_insufficient_metaspace(size_t required_size) {
+  warning("\nThe MaxMetaspaceSize of " SIZE_FORMAT " bytes is not large enough.\n"
+          "Either don't specify the -XX:MaxMetaspaceSize=<size>\n"
+          "or increase the size to at least " SIZE_FORMAT ".\n",
+          MaxMetaspaceSize, required_size);
+  exit(2);
+}
+
 static bool error_reported = false;
 
 // call this when the VM is dying--it might loosen some asserts
--- a/src/share/vm/utilities/debug.hpp	Sun Aug 19 04:29:57 2018 +0100
+++ b/src/share/vm/utilities/debug.hpp	Mon Aug 27 16:38:00 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -222,6 +222,7 @@
 void report_should_not_reach_here(const char* file, int line);
 void report_unimplemented(const char* file, int line);
 void report_untested(const char* file, int line, const char* message);
+void report_insufficient_metaspace(size_t required_size);
 
 void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2);
 
--- a/test/TEST.groups	Sun Aug 19 04:29:57 2018 +0100
+++ b/test/TEST.groups	Mon Aug 27 16:38:00 2018 +0100
@@ -96,6 +96,7 @@
   runtime/XCheckJniJsig/XCheckJSig.java \
   serviceability/attach/AttachWithStalePidFile.java \
   serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
+  serviceability/dcmd/DynLibDcmdTest.java \
   testlibrary_tests/
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/dcmd/ClassLoaderStatsTest.java	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ *
+ * @build ClassLoaderStatsTest DcmdUtil
+ * @run main ClassLoaderStatsTest
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassLoaderStatsTest {
+
+    // ClassLoader         Parent              CLD*               Classes   ChunkSz   BlockSz  Type
+    // 0x00000007c0215928  0x0000000000000000  0x0000000000000000       0         0         0  org.eclipse.osgi.baseadaptor.BaseAdaptor$1
+    // 0x00000007c0009868  0x0000000000000000  0x00007fc52aebcc80       1      6144      3768  sun.reflect.DelegatingClassLoader
+    // 0x00000007c0009868  0x0000000000000000  0x00007fc52b8916d0       1      6144      3688  sun.reflect.DelegatingClassLoader
+    // 0x00000007c0009868  0x00000007c0038ba8  0x00007fc52afb8760       1      6144      3688  sun.reflect.DelegatingClassLoader
+    // 0x00000007c0009868  0x0000000000000000  0x00007fc52afbb1a0       1      6144      3688  sun.reflect.DelegatingClassLoader
+    // 0x0000000000000000  0x0000000000000000  0x00007fc523416070    5019  30060544  29956216  <boot classloader>
+    //                                                                455   1210368    672848   + unsafe anonymous classes
+    // 0x00000007c016b5c8  0x00000007c0038ba8  0x00007fc52a995000       5      8192      5864  org.netbeans.StandardModule$OneModuleClassLoader
+    // 0x00000007c0009868  0x00000007c016b5c8  0x00007fc52ac13640       1      6144      3896  sun.reflect.DelegatingClassLoader
+    // ...
+
+    static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
+    static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
+
+    public static DummyClassLoader dummyloader;
+
+    public static void main(String arg[]) throws Exception {
+
+        // create a classloader and load our special class
+        dummyloader = new DummyClassLoader();
+        Class<?> c = Class.forName("TestClass", true, dummyloader);
+        if (c.getClassLoader() != dummyloader) {
+            throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
+        }
+
+        String result = DcmdUtil.executeDcmd("VM.classloader_stats");
+        BufferedReader r = new BufferedReader(new StringReader(result));
+        String line;
+        while((line = r.readLine()) != null) {
+            Matcher m = clLine.matcher(line);
+            if (m.matches()) {
+                // verify that DummyClassLoader has loaded 1 class and 1 anonymous class
+                if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
+                    System.out.println("line: " + line);
+                    if (!m.group(1).equals("1")) {
+                        throw new Exception("Should have loaded 1 class: " + line);
+                    }
+                    checkPositiveInt(m.group(2));
+                    checkPositiveInt(m.group(3));
+
+                    String next = r.readLine();
+                    System.out.println("next: " + next);
+                    Matcher m1 = anonLine.matcher(next);
+                    m1.matches();
+                    if (!m1.group(1).equals("1")) {
+                        throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
+                    }
+                    checkPositiveInt(m1.group(2));
+                    checkPositiveInt(m1.group(3));
+                }
+            }
+        }
+    }
+
+    private static void checkPositiveInt(String s) throws Exception {
+        if (Integer.parseInt(s) <= 0) {
+            throw new Exception("Value should have been > 0: " + s);
+        }
+    }
+
+    public static class DummyClassLoader extends ClassLoader {
+
+        public static final String CLASS_NAME = "TestClass";
+
+        static ByteBuffer readClassFile(String name)
+        {
+            File f = new File(System.getProperty("test.classes", "."),
+                              name);
+            try (FileInputStream fin = new FileInputStream(f);
+                 FileChannel fc = fin.getChannel())
+            {
+                return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+            } catch (IOException e) {
+                throw new RuntimeException("Can't open file: " + name, e);
+            }
+        }
+
+        protected Class<?> loadClass(String name, boolean resolve)
+            throws ClassNotFoundException
+        {
+            Class<?> c;
+            if (!"TestClass".equals(name)) {
+                c = super.loadClass(name, resolve);
+            } else {
+                // should not delegate to the system class loader
+                c = findClass(name);
+                if (resolve) {
+                    resolveClass(c);
+                }
+            }
+            return c;
+        }
+
+        protected Class<?> findClass(String name)
+            throws ClassNotFoundException
+        {
+            if (!"TestClass".equals(name)) {
+                throw new ClassNotFoundException("Unexpected class: " + name);
+            }
+            return defineClass(name, readClassFile(name + ".class"), null);
+        }
+    } /* DummyClassLoader */
+
+}
+
+class TestClass {
+    static {
+        // force creation of anonymous class (for the lambdaform)
+        Runnable r = () -> System.out.println("Hello");
+        r.run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/dcmd/DcmdUtil.java	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 sun.management.ManagementFactoryHelper;
+
+import com.sun.management.DiagnosticCommandMBean;
+
+public class DcmdUtil
+{
+    public static String executeDcmd(String cmd, String ... args) {
+        DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
+        Object[] dcmdArgs = {args};
+        String[] signature = {String[].class.getName()};
+
+        try {
+            System.out.print("> " + cmd + " ");
+            for (String s : args) {
+                System.out.print(s + " ");
+            }
+            System.out.println(":");
+            String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature);
+            System.out.println(result);
+            return result;
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+        return null;
+    }
+
+    private static String transform(String name) {
+        StringBuilder sb = new StringBuilder();
+        boolean toLower = true;
+        boolean toUpper = false;
+        for (int i = 0; i < name.length(); i++) {
+            char c = name.charAt(i);
+            if (c == '.' || c == '_') {
+                toLower = false;
+                toUpper = true;
+            } else {
+                if (toUpper) {
+                    toUpper = false;
+                    sb.append(Character.toUpperCase(c));
+                } else if(toLower) {
+                    sb.append(Character.toLowerCase(c));
+                } else {
+                    sb.append(c);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/dcmd/DynLibDcmdTest.java	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.util.HashSet;
+import java.util.Set;
+import com.oracle.java.testlibrary.Platform;
+
+/*
+ * @test
+ * @summary Test of VM.dynlib diagnostic command via MBean
+ * @library /testlibrary
+ * @compile DcmdUtil.java
+ * @run main DynLibDcmdTest
+ */
+
+public class DynLibDcmdTest {
+
+    public static void main(String[] args) throws Exception {
+        String result = DcmdUtil.executeDcmd("VM.dynlibs");
+
+        String osDependentBaseString = null;
+        if (Platform.isSolaris()) {
+            osDependentBaseString = "lib%s.so";
+        } else if (Platform.isWindows()) {
+            osDependentBaseString = "%s.dll";
+        } else if (Platform.isOSX()) {
+            osDependentBaseString = "lib%s.dylib";
+        } else if (Platform.isLinux()) {
+            osDependentBaseString = "lib%s.so";
+        }
+
+        if (osDependentBaseString == null) {
+            throw new Exception("Unsupported OS");
+        }
+
+        Set<String> expectedContent = new HashSet<>();
+        expectedContent.add(String.format(osDependentBaseString, "jvm"));
+        expectedContent.add(String.format(osDependentBaseString, "java"));
+        expectedContent.add(String.format(osDependentBaseString, "management"));
+
+        for(String expected : expectedContent) {
+            if (!result.contains(expected)) {
+                throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/dcmd/gc/FinalizerInfoTest.java	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/*
+ * @test
+ * @summary
+ * @library /testlibrary
+ * @run main FinalizerInfoTest
+ */
+public class FinalizerInfoTest {
+    static ReentrantLock lock = new ReentrantLock();
+    static volatile int wasInitialized = 0;
+    static volatile int wasTrapped = 0;
+    static final String cmd = "GC.finalizer_info";
+    static final int objectsCount = 1000;
+
+    class MyObject {
+        public MyObject() {
+            // Make sure object allocation/deallocation is not optimized out
+            wasInitialized += 1;
+        }
+
+        protected void finalize() {
+            // Trap the object in a finalization queue
+            wasTrapped += 1;
+            lock.lock();
+        }
+    }
+
+    void run() throws Exception {
+        try {
+            lock.lock();
+            for(int i = 0; i < objectsCount; ++i) {
+                new MyObject();
+            }
+            System.out.println("Objects initialized: " + objectsCount);
+            System.gc();
+
+            while(wasTrapped < 1) {
+                // Waiting for gc thread.
+            }
+
+
+            String pid = Integer.toString(ProcessTools.getProcessId());
+            ProcessBuilder pb = new ProcessBuilder();
+            pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, cmd});
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.shouldContain("MyObject");
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new  FinalizerInfoTest().run();
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/dcmd/gc/HeapInfoTest.java	Mon Aug 27 16:38:00 2018 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.heap_info
+ * @library /testlibrary
+ * @run main HeapInfoTest
+ */
+public class HeapInfoTest {
+
+    public static void main(String[] args) throws Exception {
+        String pid = Integer.toString(ProcessTools.getProcessId());
+        ProcessBuilder pb = new ProcessBuilder();
+        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "GC.heap_info"});
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Metaspace");
+    }
+}
+