Merge

Mon, 08 Jan 2018 22:39:26 -0800

author
asaha
date
Mon, 08 Jan 2018 22:39:26 -0800
changeset 9281
da34529f2f3d
parent 9280
a02ed45fe13f
parent 9066
c19c5b73704e
child 9282
a1a3d50d9440

Merge

.hgtags file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Wed Jan 03 14:23:36 2018 -0800
     1.2 +++ b/.hgtags	Mon Jan 08 22:39:26 2018 -0800
     1.3 @@ -1127,3 +1127,4 @@
     1.4  69aec2ca5d905dde1d0f29a89076d02a531808a3 jdk8u162-b12
     1.5  f299cf0b7baea1ae85f139f97adb9ab5499f402a jdk8u172-b00
     1.6  d10254debf7c1342416062bf1ba5258f16a8ce00 jdk8u172-b01
     1.7 +653d9e0cd3f4023675c9eece7f0d563287f1d34f jdk8u172-b02
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/share/vm/classfile/classLoaderStats.cpp	Mon Jan 08 22:39:26 2018 -0800
     2.3 @@ -0,0 +1,167 @@
     2.4 +/*
     2.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + *
    2.26 + */
    2.27 +
    2.28 +#include "precompiled.hpp"
    2.29 +#include "classfile/classLoaderStats.hpp"
    2.30 +#include "utilities/globalDefinitions.hpp"
    2.31 +
    2.32 +
    2.33 +class ClassStatsClosure : public KlassClosure {
    2.34 +public:
    2.35 +  int _num_classes;
    2.36 +
    2.37 +  ClassStatsClosure() :
    2.38 +    _num_classes(0) {
    2.39 +  }
    2.40 +
    2.41 +  virtual void do_klass(Klass* k) {
    2.42 +    _num_classes++;
    2.43 +  }
    2.44 +};
    2.45 +
    2.46 +
    2.47 +void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
    2.48 +  oop cl = cld->class_loader();
    2.49 +  ClassLoaderStats* cls;
    2.50 +
    2.51 +  // The hashtable key is the ClassLoader oop since we want to account
    2.52 +  // for "real" classes and anonymous classes together
    2.53 +  ClassLoaderStats** cls_ptr = _stats->get(cl);
    2.54 +  if (cls_ptr == NULL) {
    2.55 +    cls = new ClassLoaderStats();
    2.56 +    _stats->put(cl, cls);
    2.57 +    _total_loaders++;
    2.58 +  } else {
    2.59 +    cls = *cls_ptr;
    2.60 +  }
    2.61 +
    2.62 +  if (!cld->is_anonymous()) {
    2.63 +    cls->_cld = cld;
    2.64 +  }
    2.65 +
    2.66 +  cls->_class_loader = cl;
    2.67 +  if (cl != NULL) {
    2.68 +    cls->_parent = java_lang_ClassLoader::parent(cl);
    2.69 +    addEmptyParents(cls->_parent);
    2.70 +  }
    2.71 +
    2.72 +  ClassStatsClosure csc;
    2.73 +  cld->classes_do(&csc);
    2.74 +  if(cld->is_anonymous()) {
    2.75 +    cls->_anon_classes_count += csc._num_classes;
    2.76 +  } else {
    2.77 +    cls->_classes_count = csc._num_classes;
    2.78 +  }
    2.79 +  _total_classes += csc._num_classes;
    2.80 +
    2.81 +  Metaspace* ms = cld->metaspace_or_null();
    2.82 +  if (ms != NULL) {
    2.83 +    if(cld->is_anonymous()) {
    2.84 +      cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
    2.85 +      cls->_anon_block_sz += ms->allocated_blocks_bytes();
    2.86 +    } else {
    2.87 +      cls->_chunk_sz = ms->allocated_chunks_bytes();
    2.88 +      cls->_block_sz = ms->allocated_blocks_bytes();
    2.89 +    }
    2.90 +    _total_chunk_sz += ms->allocated_chunks_bytes();
    2.91 +    _total_block_sz += ms->allocated_blocks_bytes();
    2.92 +  }
    2.93 +}
    2.94 +
    2.95 +
    2.96 +// Handles the difference in pointer width on 32 and 64 bit platforms
    2.97 +#ifdef _LP64
    2.98 +  #define SPACE "%8s"
    2.99 +#else
   2.100 +  #define SPACE "%s"
   2.101 +#endif
   2.102 +
   2.103 +
   2.104 +bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
   2.105 +  Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
   2.106 +  Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
   2.107 +
   2.108 +  _out->print(INTPTR_FORMAT "  " INTPTR_FORMAT "  " INTPTR_FORMAT "  " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
   2.109 +      p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
   2.110 +      cls->_classes_count,
   2.111 +      cls->_chunk_sz, cls->_block_sz);
   2.112 +  if (class_loader_klass != NULL) {
   2.113 +    _out->print("%s", class_loader_klass->external_name());
   2.114 +  } else {
   2.115 +    _out->print("<boot class loader>");
   2.116 +  }
   2.117 +  _out->cr();
   2.118 +  if (cls->_anon_classes_count > 0) {
   2.119 +    _out->print_cr(SPACE SPACE SPACE "                                    " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "   + unsafe anonymous classes",
   2.120 +        "", "", "",
   2.121 +        cls->_anon_classes_count,
   2.122 +        cls->_anon_chunk_sz, cls->_anon_block_sz);
   2.123 +  }
   2.124 +  return true;
   2.125 +}
   2.126 +
   2.127 +
   2.128 +void ClassLoaderStatsClosure::print() {
   2.129 +  _out->print_cr("ClassLoader" SPACE " Parent" SPACE "      CLD*" SPACE "       Classes   ChunkSz   BlockSz  Type", "", "", "");
   2.130 +  _stats->iterate(this);
   2.131 +  _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders);
   2.132 +  _out->print(SPACE SPACE SPACE "                      ", "", "", "");
   2.133 +  _out->print_cr(UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
   2.134 +      _total_classes,
   2.135 +      _total_chunk_sz,
   2.136 +      _total_block_sz);
   2.137 +  _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks");
   2.138 +  _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)");
   2.139 +}
   2.140 +
   2.141 +
   2.142 +void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
   2.143 +  while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
   2.144 +    // This classloader has not loaded any classes
   2.145 +    ClassLoaderStats** cls_ptr = _stats->get(cl);
   2.146 +    if (cls_ptr == NULL) {
   2.147 +      // It does not exist in our table - add it
   2.148 +      ClassLoaderStats* cls = new ClassLoaderStats();
   2.149 +      cls->_class_loader = cl;
   2.150 +      cls->_parent = java_lang_ClassLoader::parent(cl);
   2.151 +      _stats->put(cl, cls);
   2.152 +      _total_loaders++;
   2.153 +    }
   2.154 +
   2.155 +    cl = java_lang_ClassLoader::parent(cl);
   2.156 +  }
   2.157 +}
   2.158 +
   2.159 +
   2.160 +void ClassLoaderStatsVMOperation::doit() {
   2.161 +  ClassLoaderStatsClosure clsc (_out);
   2.162 +  ClassLoaderDataGraph::cld_do(&clsc);
   2.163 +  clsc.print();
   2.164 +}
   2.165 +
   2.166 +
   2.167 +void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) {
   2.168 +  ClassLoaderStatsVMOperation op(output());
   2.169 +  VMThread::execute(&op);
   2.170 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/share/vm/classfile/classLoaderStats.hpp	Mon Jan 08 22:39:26 2018 -0800
     3.3 @@ -0,0 +1,152 @@
     3.4 +/*
     3.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + *
    3.26 + */
    3.27 +
    3.28 +#ifndef SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
    3.29 +#define SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
    3.30 +
    3.31 +
    3.32 +#include "classfile/classLoaderData.hpp"
    3.33 +#include "oops/klass.hpp"
    3.34 +#include "oops/oopsHierarchy.hpp"
    3.35 +#include "runtime/vm_operations.hpp"
    3.36 +#include "services/diagnosticCommand.hpp"
    3.37 +#include "utilities/resourceHash.hpp"
    3.38 +
    3.39 +
    3.40 +class ClassLoaderStatsDCmd : public DCmd {
    3.41 +public:
    3.42 +  ClassLoaderStatsDCmd(outputStream* output, bool heap) :
    3.43 +    DCmd(output, heap) {
    3.44 +  }
    3.45 +
    3.46 +  static const char* name() {
    3.47 +    return "VM.classloader_stats";
    3.48 +  }
    3.49 +
    3.50 +  static const char* description() {
    3.51 +    return "Print statistics about all ClassLoaders.";
    3.52 +  }
    3.53 +
    3.54 +  static const char* impact() {
    3.55 +    return "Low";
    3.56 +  }
    3.57 +
    3.58 +  virtual void execute(DCmdSource source, TRAPS);
    3.59 +
    3.60 +  static int num_arguments() {
    3.61 +    return 0;
    3.62 +  }
    3.63 +
    3.64 +  static const JavaPermission permission() {
    3.65 +    JavaPermission p = {"java.lang.management.ManagementPermission",
    3.66 +                        "monitor", NULL};
    3.67 +    return p;
    3.68 +  }
    3.69 +};
    3.70 +
    3.71 +
    3.72 +class ClassLoaderStats : public ResourceObj {
    3.73 +public:
    3.74 +  ClassLoaderData*  _cld;
    3.75 +  oop               _class_loader;
    3.76 +  oop               _parent;
    3.77 +
    3.78 +  size_t            _chunk_sz;
    3.79 +  size_t            _block_sz;
    3.80 +  uintx             _classes_count;
    3.81 +
    3.82 +  size_t            _anon_chunk_sz;
    3.83 +  size_t            _anon_block_sz;
    3.84 +  uintx             _anon_classes_count;
    3.85 +
    3.86 +  ClassLoaderStats() :
    3.87 +    _cld(0),
    3.88 +    _class_loader(0),
    3.89 +    _parent(0),
    3.90 +    _chunk_sz(0),
    3.91 +    _block_sz(0),
    3.92 +    _classes_count(0),
    3.93 +    _anon_block_sz(0),
    3.94 +    _anon_chunk_sz(0),
    3.95 +    _anon_classes_count(0) {
    3.96 +  }
    3.97 +};
    3.98 +
    3.99 +
   3.100 +class ClassLoaderStatsClosure : public CLDClosure {
   3.101 +protected:
   3.102 +  static bool oop_equals(oop const& s1, oop const& s2) {
   3.103 +    return s1 == s2;
   3.104 +  }
   3.105 +
   3.106 +  static unsigned oop_hash(oop const& s1) {
   3.107 +    unsigned hash = (unsigned)((uintptr_t)&s1);
   3.108 +    return hash ^ (hash >> LogMinObjAlignment);
   3.109 +  }
   3.110 +
   3.111 +  typedef ResourceHashtable<oop, ClassLoaderStats*,
   3.112 +      ClassLoaderStatsClosure::oop_hash, ClassLoaderStatsClosure::oop_equals> StatsTable;
   3.113 +
   3.114 +  outputStream* _out;
   3.115 +  StatsTable* _stats;
   3.116 +  uintx   _total_loaders;
   3.117 +  uintx   _total_classes;
   3.118 +  size_t  _total_chunk_sz;
   3.119 +  size_t  _total_block_sz;
   3.120 +
   3.121 +public:
   3.122 +  ClassLoaderStatsClosure(outputStream* out) :
   3.123 +    _out(out),
   3.124 +    _total_loaders(0),
   3.125 +    _total_block_sz(0),
   3.126 +    _total_chunk_sz(0),
   3.127 +    _total_classes(0),
   3.128 +    _stats(new StatsTable()) {
   3.129 +  }
   3.130 +
   3.131 +  virtual void do_cld(ClassLoaderData* cld);
   3.132 +  virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls);
   3.133 +  void print();
   3.134 +
   3.135 +private:
   3.136 +  void addEmptyParents(oop cl);
   3.137 +};
   3.138 +
   3.139 +
   3.140 +class ClassLoaderStatsVMOperation : public VM_Operation {
   3.141 +  outputStream* _out;
   3.142 +
   3.143 +public:
   3.144 +  ClassLoaderStatsVMOperation(outputStream* out) :
   3.145 +    _out(out) {
   3.146 +  }
   3.147 +
   3.148 +  VMOp_Type type() const {
   3.149 +    return VMOp_ClassLoaderStatsOperation;
   3.150 +  }
   3.151 +
   3.152 +  void doit();
   3.153 +};
   3.154 +
   3.155 +#endif // SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
     4.1 --- a/src/share/vm/memory/metaspace.cpp	Wed Jan 03 14:23:36 2018 -0800
     4.2 +++ b/src/share/vm/memory/metaspace.cpp	Mon Jan 08 22:39:26 2018 -0800
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -154,7 +154,7 @@
    4.11  
    4.12    // Map a size to a list index assuming that there are lists
    4.13    // for special, small, medium, and humongous chunks.
    4.14 -  static ChunkIndex list_index(size_t size);
    4.15 +  ChunkIndex list_index(size_t size);
    4.16  
    4.17    // Remove the chunk from its freelist.  It is
    4.18    // expected to be on one of the _free_chunks[] lists.
    4.19 @@ -706,6 +706,7 @@
    4.20    size_t allocated_blocks_words() const { return _allocated_blocks_words; }
    4.21    size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
    4.22    size_t allocated_chunks_words() const { return _allocated_chunks_words; }
    4.23 +  size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; }
    4.24    size_t allocated_chunks_count() const { return _allocated_chunks_count; }
    4.25  
    4.26    bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
    4.27 @@ -1751,7 +1752,11 @@
    4.28    st->print_cr("Sum free chunk total " SIZE_FORMAT "  count " SIZE_FORMAT,
    4.29                  sum_free_chunks(), sum_free_chunks_count());
    4.30  }
    4.31 +
    4.32  ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
    4.33 +  assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex,
    4.34 +         err_msg("Bad index: %d", (int)index));
    4.35 +
    4.36    return &_free_chunks[index];
    4.37  }
    4.38  
    4.39 @@ -1863,7 +1868,7 @@
    4.40    }
    4.41  
    4.42    assert((word_size <= chunk->word_size()) ||
    4.43 -         list_index(chunk->word_size() == HumongousIndex),
    4.44 +         (list_index(chunk->word_size()) == HumongousIndex),
    4.45           "Non-humongous variable sized chunk");
    4.46    if (TraceMetadataChunkAllocation) {
    4.47      size_t list_count;
    4.48 @@ -2357,22 +2362,18 @@
    4.49  }
    4.50  
    4.51  ChunkIndex ChunkManager::list_index(size_t size) {
    4.52 -  switch (size) {
    4.53 -    case SpecializedChunk:
    4.54 -      assert(SpecializedChunk == ClassSpecializedChunk,
    4.55 -             "Need branch for ClassSpecializedChunk");
    4.56 -      return SpecializedIndex;
    4.57 -    case SmallChunk:
    4.58 -    case ClassSmallChunk:
    4.59 -      return SmallIndex;
    4.60 -    case MediumChunk:
    4.61 -    case ClassMediumChunk:
    4.62 -      return MediumIndex;
    4.63 -    default:
    4.64 -      assert(size > MediumChunk || size > ClassMediumChunk,
    4.65 -             "Not a humongous chunk");
    4.66 -      return HumongousIndex;
    4.67 +  if (free_chunks(SpecializedIndex)->size() == size) {
    4.68 +    return SpecializedIndex;
    4.69    }
    4.70 +  if (free_chunks(SmallIndex)->size() == size) {
    4.71 +    return SmallIndex;
    4.72 +  }
    4.73 +  if (free_chunks(MediumIndex)->size() == size) {
    4.74 +    return MediumIndex;
    4.75 +  }
    4.76 +
    4.77 +  assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk");
    4.78 +  return HumongousIndex;
    4.79  }
    4.80  
    4.81  void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
    4.82 @@ -2394,7 +2395,7 @@
    4.83  
    4.84    // Find the correct list and and set the current
    4.85    // chunk for that list.
    4.86 -  ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
    4.87 +  ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size());
    4.88  
    4.89    if (index != HumongousIndex) {
    4.90      retire_current_chunk();
    4.91 @@ -3463,6 +3464,16 @@
    4.92    return capacity_words_slow(mdtype) * BytesPerWord;
    4.93  }
    4.94  
    4.95 +size_t Metaspace::allocated_blocks_bytes() const {
    4.96 +  return vsm()->allocated_blocks_bytes() +
    4.97 +      (using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0);
    4.98 +}
    4.99 +
   4.100 +size_t Metaspace::allocated_chunks_bytes() const {
   4.101 +  return vsm()->allocated_chunks_bytes() +
   4.102 +      (using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0);
   4.103 +}
   4.104 +
   4.105  void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
   4.106    if (SafepointSynchronize::is_at_safepoint()) {
   4.107      if (DumpSharedSpaces && PrintSharedSpaces) {
   4.108 @@ -4020,4 +4031,40 @@
   4.109    SpaceManagerTest::test_adjust_initial_chunk_size();
   4.110  }
   4.111  
   4.112 +// The following test is placed here instead of a gtest / unittest file
   4.113 +// because the ChunkManager class is only available in this file.
   4.114 +void ChunkManager_test_list_index() {
   4.115 +  ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk);
   4.116 +
   4.117 +  // Test previous bug where a query for a humongous class metachunk,
   4.118 +  // incorrectly matched the non-class medium metachunk size.
   4.119 +  {
   4.120 +    assert(MediumChunk > ClassMediumChunk, "Precondition for test");
   4.121 +
   4.122 +    ChunkIndex index = manager.list_index(MediumChunk);
   4.123 +
   4.124 +    assert(index == HumongousIndex,
   4.125 +           err_msg("Requested size is larger than ClassMediumChunk,"
   4.126 +           " so should return HumongousIndex. Got index: %d", (int)index));
   4.127 +  }
   4.128 +
   4.129 +  // Check the specified sizes as well.
   4.130 +  {
   4.131 +    ChunkIndex index = manager.list_index(ClassSpecializedChunk);
   4.132 +    assert(index == SpecializedIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   4.133 +  }
   4.134 +  {
   4.135 +    ChunkIndex index = manager.list_index(ClassSmallChunk);
   4.136 +    assert(index == SmallIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   4.137 +  }
   4.138 +  {
   4.139 +    ChunkIndex index = manager.list_index(ClassMediumChunk);
   4.140 +    assert(index == MediumIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   4.141 +  }
   4.142 +  {
   4.143 +    ChunkIndex index = manager.list_index(ClassMediumChunk + 1);
   4.144 +    assert(index == HumongousIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   4.145 +  }
   4.146 +}
   4.147 +
   4.148  #endif
     5.1 --- a/src/share/vm/memory/metaspace.hpp	Wed Jan 03 14:23:36 2018 -0800
     5.2 +++ b/src/share/vm/memory/metaspace.hpp	Mon Jan 08 22:39:26 2018 -0800
     5.3 @@ -232,6 +232,9 @@
     5.4    size_t used_bytes_slow(MetadataType mdtype) const;
     5.5    size_t capacity_bytes_slow(MetadataType mdtype) const;
     5.6  
     5.7 +  size_t allocated_blocks_bytes() const;
     5.8 +  size_t allocated_chunks_bytes() const;
     5.9 +
    5.10    static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
    5.11                              bool read_only, MetaspaceObj::Type type, TRAPS);
    5.12    void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
     6.1 --- a/src/share/vm/prims/jni.cpp	Wed Jan 03 14:23:36 2018 -0800
     6.2 +++ b/src/share/vm/prims/jni.cpp	Mon Jan 08 22:39:26 2018 -0800
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
     6.7   * Copyright (c) 2012 Red Hat, Inc.
     6.8   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.9   *
    6.10 @@ -5106,6 +5106,7 @@
    6.11  void TestBufferingOopClosure_test();
    6.12  void TestCodeCacheRemSet_test();
    6.13  void FreeRegionList_test();
    6.14 +void ChunkManager_test_list_index();
    6.15  #endif
    6.16  
    6.17  void execute_internal_vm_tests() {
    6.18 @@ -5139,6 +5140,7 @@
    6.19      run_unit_test(TestG1BiasedArray_test());
    6.20      run_unit_test(HeapRegionRemSet::test_prt());
    6.21      run_unit_test(SpaceManager_test_adjust_initial_chunk_size());
    6.22 +    run_unit_test(ChunkManager_test_list_index());
    6.23      run_unit_test(TestBufferingOopClosure_test());
    6.24      run_unit_test(TestCodeCacheRemSet_test());
    6.25      if (UseG1GC) {
     7.1 --- a/src/share/vm/runtime/vm_operations.hpp	Wed Jan 03 14:23:36 2018 -0800
     7.2 +++ b/src/share/vm/runtime/vm_operations.hpp	Mon Jan 08 22:39:26 2018 -0800
     7.3 @@ -97,6 +97,7 @@
     7.4    template(LinuxDllLoad)                          \
     7.5    template(RotateGCLog)                           \
     7.6    template(WhiteBoxOperation)                     \
     7.7 +  template(ClassLoaderStatsOperation)             \
     7.8  
     7.9  class VM_Operation: public CHeapObj<mtInternal> {
    7.10   public:
     8.1 --- a/src/share/vm/services/diagnosticCommand.cpp	Wed Jan 03 14:23:36 2018 -0800
     8.2 +++ b/src/share/vm/services/diagnosticCommand.cpp	Mon Jan 08 22:39:26 2018 -0800
     8.3 @@ -23,6 +23,7 @@
     8.4   */
     8.5  
     8.6  #include "precompiled.hpp"
     8.7 +#include "classfile/classLoaderStats.hpp"
     8.8  #include "gc_implementation/shared/vmGCOperations.hpp"
     8.9  #include "runtime/javaCalls.hpp"
    8.10  #include "runtime/os.hpp"
    8.11 @@ -61,6 +62,7 @@
    8.12  #endif // INCLUDE_SERVICES
    8.13    DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
    8.14    DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
    8.15 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
    8.16  
    8.17    // Enhanced JMX Agent Support
    8.18    // These commands won't be exported via the DiagnosticCommandMBean until an
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/serviceability/dcmd/ClassLoaderStatsTest.java	Mon Jan 08 22:39:26 2018 -0800
     9.3 @@ -0,0 +1,155 @@
     9.4 +/*
     9.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + *
    9.30 + * @build ClassLoaderStatsTest DcmdUtil
    9.31 + * @run main ClassLoaderStatsTest
    9.32 + */
    9.33 +
    9.34 +import java.io.BufferedReader;
    9.35 +import java.io.File;
    9.36 +import java.io.FileInputStream;
    9.37 +import java.io.IOException;
    9.38 +import java.io.StringReader;
    9.39 +import java.nio.ByteBuffer;
    9.40 +import java.nio.channels.FileChannel;
    9.41 +import java.util.regex.Matcher;
    9.42 +import java.util.regex.Pattern;
    9.43 +
    9.44 +public class ClassLoaderStatsTest {
    9.45 +
    9.46 +    // ClassLoader         Parent              CLD*               Classes   ChunkSz   BlockSz  Type
    9.47 +    // 0x00000007c0215928  0x0000000000000000  0x0000000000000000       0         0         0  org.eclipse.osgi.baseadaptor.BaseAdaptor$1
    9.48 +    // 0x00000007c0009868  0x0000000000000000  0x00007fc52aebcc80       1      6144      3768  sun.reflect.DelegatingClassLoader
    9.49 +    // 0x00000007c0009868  0x0000000000000000  0x00007fc52b8916d0       1      6144      3688  sun.reflect.DelegatingClassLoader
    9.50 +    // 0x00000007c0009868  0x00000007c0038ba8  0x00007fc52afb8760       1      6144      3688  sun.reflect.DelegatingClassLoader
    9.51 +    // 0x00000007c0009868  0x0000000000000000  0x00007fc52afbb1a0       1      6144      3688  sun.reflect.DelegatingClassLoader
    9.52 +    // 0x0000000000000000  0x0000000000000000  0x00007fc523416070    5019  30060544  29956216  <boot classloader>
    9.53 +    //                                                                455   1210368    672848   + unsafe anonymous classes
    9.54 +    // 0x00000007c016b5c8  0x00000007c0038ba8  0x00007fc52a995000       5      8192      5864  org.netbeans.StandardModule$OneModuleClassLoader
    9.55 +    // 0x00000007c0009868  0x00000007c016b5c8  0x00007fc52ac13640       1      6144      3896  sun.reflect.DelegatingClassLoader
    9.56 +    // ...
    9.57 +
    9.58 +    static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
    9.59 +    static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
    9.60 +
    9.61 +    public static DummyClassLoader dummyloader;
    9.62 +
    9.63 +    public static void main(String arg[]) throws Exception {
    9.64 +
    9.65 +        // create a classloader and load our special class
    9.66 +        dummyloader = new DummyClassLoader();
    9.67 +        Class<?> c = Class.forName("TestClass", true, dummyloader);
    9.68 +        if (c.getClassLoader() != dummyloader) {
    9.69 +            throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
    9.70 +        }
    9.71 +
    9.72 +        String result = DcmdUtil.executeDcmd("VM.classloader_stats");
    9.73 +        BufferedReader r = new BufferedReader(new StringReader(result));
    9.74 +        String line;
    9.75 +        while((line = r.readLine()) != null) {
    9.76 +            Matcher m = clLine.matcher(line);
    9.77 +            if (m.matches()) {
    9.78 +                // verify that DummyClassLoader has loaded 1 class and 1 anonymous class
    9.79 +                if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
    9.80 +                    System.out.println("line: " + line);
    9.81 +                    if (!m.group(1).equals("1")) {
    9.82 +                        throw new Exception("Should have loaded 1 class: " + line);
    9.83 +                    }
    9.84 +                    checkPositiveInt(m.group(2));
    9.85 +                    checkPositiveInt(m.group(3));
    9.86 +
    9.87 +                    String next = r.readLine();
    9.88 +                    System.out.println("next: " + next);
    9.89 +                    Matcher m1 = anonLine.matcher(next);
    9.90 +                    m1.matches();
    9.91 +                    if (!m1.group(1).equals("1")) {
    9.92 +                        throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
    9.93 +                    }
    9.94 +                    checkPositiveInt(m1.group(2));
    9.95 +                    checkPositiveInt(m1.group(3));
    9.96 +                }
    9.97 +            }
    9.98 +        }
    9.99 +    }
   9.100 +
   9.101 +    private static void checkPositiveInt(String s) throws Exception {
   9.102 +        if (Integer.parseInt(s) <= 0) {
   9.103 +            throw new Exception("Value should have been > 0: " + s);
   9.104 +        }
   9.105 +    }
   9.106 +
   9.107 +    public static class DummyClassLoader extends ClassLoader {
   9.108 +
   9.109 +        public static final String CLASS_NAME = "TestClass";
   9.110 +
   9.111 +        static ByteBuffer readClassFile(String name)
   9.112 +        {
   9.113 +            File f = new File(System.getProperty("test.classes", "."),
   9.114 +                              name);
   9.115 +            try (FileInputStream fin = new FileInputStream(f);
   9.116 +                 FileChannel fc = fin.getChannel())
   9.117 +            {
   9.118 +                return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
   9.119 +            } catch (IOException e) {
   9.120 +                throw new RuntimeException("Can't open file: " + name, e);
   9.121 +            }
   9.122 +        }
   9.123 +
   9.124 +        protected Class<?> loadClass(String name, boolean resolve)
   9.125 +            throws ClassNotFoundException
   9.126 +        {
   9.127 +            Class<?> c;
   9.128 +            if (!"TestClass".equals(name)) {
   9.129 +                c = super.loadClass(name, resolve);
   9.130 +            } else {
   9.131 +                // should not delegate to the system class loader
   9.132 +                c = findClass(name);
   9.133 +                if (resolve) {
   9.134 +                    resolveClass(c);
   9.135 +                }
   9.136 +            }
   9.137 +            return c;
   9.138 +        }
   9.139 +
   9.140 +        protected Class<?> findClass(String name)
   9.141 +            throws ClassNotFoundException
   9.142 +        {
   9.143 +            if (!"TestClass".equals(name)) {
   9.144 +                throw new ClassNotFoundException("Unexpected class: " + name);
   9.145 +            }
   9.146 +            return defineClass(name, readClassFile(name + ".class"), null);
   9.147 +        }
   9.148 +    } /* DummyClassLoader */
   9.149 +
   9.150 +}
   9.151 +
   9.152 +class TestClass {
   9.153 +    static {
   9.154 +        // force creation of anonymous class (for the lambdaform)
   9.155 +        Runnable r = () -> System.out.println("Hello");
   9.156 +        r.run();
   9.157 +    }
   9.158 +}

mercurial