Fri, 26 Jan 2018 09:59:10 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
src/share/vm/classfile/vmSymbols.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Mon Jan 22 14:27:46 2018 -0500 1.2 +++ b/.hgtags Fri Jan 26 09:59:10 2018 -0800 1.3 @@ -1134,4 +1134,9 @@ 1.4 a17bab9405474602b18cd62e060a09b17d6413ac jdk8u171-b00 1.5 ebfd57cc21e6b7f0c22b17c666b6b28c9340e207 jdk8u171-b01 1.6 1acd7c1b80241def8fac90f70b0df16356adad47 jdk8u171-b02 1.7 +5587cde50bbc2aa031aefb47eaa36b041f5e7c4b jdk8u171-b03 1.8 +f299cf0b7baea1ae85f139f97adb9ab5499f402a jdk8u172-b00 1.9 +d10254debf7c1342416062bf1ba5258f16a8ce00 jdk8u172-b01 1.10 +653d9e0cd3f4023675c9eece7f0d563287f1d34f jdk8u172-b02 1.11 +771d9e1fbe1ae2ec4d5d937ebcbfd18e9c800098 jdk8u172-b03 1.12 5587cde50bbc2aa031aefb47eaa36b041f5e7c4b jdk8u181-b00
2.1 --- a/src/os/bsd/vm/os_bsd.cpp Mon Jan 22 14:27:46 2018 -0500 2.2 +++ b/src/os/bsd/vm/os_bsd.cpp Fri Jan 26 09:59:10 2018 -0800 2.3 @@ -1681,14 +1681,9 @@ 2.4 2.5 dlclose(handle); 2.6 #elif defined(__APPLE__) 2.7 - uint32_t count; 2.8 - uint32_t i; 2.9 - 2.10 - count = _dyld_image_count(); 2.11 - for (i = 1; i < count; i++) { 2.12 - const char *name = _dyld_get_image_name(i); 2.13 - intptr_t slide = _dyld_get_image_vmaddr_slide(i); 2.14 - st->print_cr(PTR_FORMAT " \t%s", slide, name); 2.15 + for (uint32_t i = 1; i < _dyld_image_count(); i++) { 2.16 + st->print_cr(PTR_FORMAT " \t%s", _dyld_get_image_header(i), 2.17 + _dyld_get_image_name(i)); 2.18 } 2.19 #else 2.20 st->print_cr("Error: Cannot print dynamic libraries.");
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/share/vm/classfile/classLoaderStats.cpp Fri Jan 26 09:59:10 2018 -0800 3.3 @@ -0,0 +1,167 @@ 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 +#include "precompiled.hpp" 3.29 +#include "classfile/classLoaderStats.hpp" 3.30 +#include "utilities/globalDefinitions.hpp" 3.31 + 3.32 + 3.33 +class ClassStatsClosure : public KlassClosure { 3.34 +public: 3.35 + int _num_classes; 3.36 + 3.37 + ClassStatsClosure() : 3.38 + _num_classes(0) { 3.39 + } 3.40 + 3.41 + virtual void do_klass(Klass* k) { 3.42 + _num_classes++; 3.43 + } 3.44 +}; 3.45 + 3.46 + 3.47 +void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) { 3.48 + oop cl = cld->class_loader(); 3.49 + ClassLoaderStats* cls; 3.50 + 3.51 + // The hashtable key is the ClassLoader oop since we want to account 3.52 + // for "real" classes and anonymous classes together 3.53 + ClassLoaderStats** cls_ptr = _stats->get(cl); 3.54 + if (cls_ptr == NULL) { 3.55 + cls = new ClassLoaderStats(); 3.56 + _stats->put(cl, cls); 3.57 + _total_loaders++; 3.58 + } else { 3.59 + cls = *cls_ptr; 3.60 + } 3.61 + 3.62 + if (!cld->is_anonymous()) { 3.63 + cls->_cld = cld; 3.64 + } 3.65 + 3.66 + cls->_class_loader = cl; 3.67 + if (cl != NULL) { 3.68 + cls->_parent = java_lang_ClassLoader::parent(cl); 3.69 + addEmptyParents(cls->_parent); 3.70 + } 3.71 + 3.72 + ClassStatsClosure csc; 3.73 + cld->classes_do(&csc); 3.74 + if(cld->is_anonymous()) { 3.75 + cls->_anon_classes_count += csc._num_classes; 3.76 + } else { 3.77 + cls->_classes_count = csc._num_classes; 3.78 + } 3.79 + _total_classes += csc._num_classes; 3.80 + 3.81 + Metaspace* ms = cld->metaspace_or_null(); 3.82 + if (ms != NULL) { 3.83 + if(cld->is_anonymous()) { 3.84 + cls->_anon_chunk_sz += ms->allocated_chunks_bytes(); 3.85 + cls->_anon_block_sz += ms->allocated_blocks_bytes(); 3.86 + } else { 3.87 + cls->_chunk_sz = ms->allocated_chunks_bytes(); 3.88 + cls->_block_sz = ms->allocated_blocks_bytes(); 3.89 + } 3.90 + _total_chunk_sz += ms->allocated_chunks_bytes(); 3.91 + _total_block_sz += ms->allocated_blocks_bytes(); 3.92 + } 3.93 +} 3.94 + 3.95 + 3.96 +// Handles the difference in pointer width on 32 and 64 bit platforms 3.97 +#ifdef _LP64 3.98 + #define SPACE "%8s" 3.99 +#else 3.100 + #define SPACE "%s" 3.101 +#endif 3.102 + 3.103 + 3.104 +bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) { 3.105 + Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass()); 3.106 + Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass()); 3.107 + 3.108 + _out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", 3.109 + p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld), 3.110 + cls->_classes_count, 3.111 + cls->_chunk_sz, cls->_block_sz); 3.112 + if (class_loader_klass != NULL) { 3.113 + _out->print("%s", class_loader_klass->external_name()); 3.114 + } else { 3.115 + _out->print("<boot class loader>"); 3.116 + } 3.117 + _out->cr(); 3.118 + if (cls->_anon_classes_count > 0) { 3.119 + _out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + unsafe anonymous classes", 3.120 + "", "", "", 3.121 + cls->_anon_classes_count, 3.122 + cls->_anon_chunk_sz, cls->_anon_block_sz); 3.123 + } 3.124 + return true; 3.125 +} 3.126 + 3.127 + 3.128 +void ClassLoaderStatsClosure::print() { 3.129 + _out->print_cr("ClassLoader" SPACE " Parent" SPACE " CLD*" SPACE " Classes ChunkSz BlockSz Type", "", "", ""); 3.130 + _stats->iterate(this); 3.131 + _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders); 3.132 + _out->print(SPACE SPACE SPACE " ", "", "", ""); 3.133 + _out->print_cr(UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", 3.134 + _total_classes, 3.135 + _total_chunk_sz, 3.136 + _total_block_sz); 3.137 + _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks"); 3.138 + _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)"); 3.139 +} 3.140 + 3.141 + 3.142 +void ClassLoaderStatsClosure::addEmptyParents(oop cl) { 3.143 + while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) { 3.144 + // This classloader has not loaded any classes 3.145 + ClassLoaderStats** cls_ptr = _stats->get(cl); 3.146 + if (cls_ptr == NULL) { 3.147 + // It does not exist in our table - add it 3.148 + ClassLoaderStats* cls = new ClassLoaderStats(); 3.149 + cls->_class_loader = cl; 3.150 + cls->_parent = java_lang_ClassLoader::parent(cl); 3.151 + _stats->put(cl, cls); 3.152 + _total_loaders++; 3.153 + } 3.154 + 3.155 + cl = java_lang_ClassLoader::parent(cl); 3.156 + } 3.157 +} 3.158 + 3.159 + 3.160 +void ClassLoaderStatsVMOperation::doit() { 3.161 + ClassLoaderStatsClosure clsc (_out); 3.162 + ClassLoaderDataGraph::cld_do(&clsc); 3.163 + clsc.print(); 3.164 +} 3.165 + 3.166 + 3.167 +void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) { 3.168 + ClassLoaderStatsVMOperation op(output()); 3.169 + VMThread::execute(&op); 3.170 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/share/vm/classfile/classLoaderStats.hpp Fri Jan 26 09:59:10 2018 -0800 4.3 @@ -0,0 +1,152 @@ 4.4 +/* 4.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + * 4.26 + */ 4.27 + 4.28 +#ifndef SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP 4.29 +#define SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP 4.30 + 4.31 + 4.32 +#include "classfile/classLoaderData.hpp" 4.33 +#include "oops/klass.hpp" 4.34 +#include "oops/oopsHierarchy.hpp" 4.35 +#include "runtime/vm_operations.hpp" 4.36 +#include "services/diagnosticCommand.hpp" 4.37 +#include "utilities/resourceHash.hpp" 4.38 + 4.39 + 4.40 +class ClassLoaderStatsDCmd : public DCmd { 4.41 +public: 4.42 + ClassLoaderStatsDCmd(outputStream* output, bool heap) : 4.43 + DCmd(output, heap) { 4.44 + } 4.45 + 4.46 + static const char* name() { 4.47 + return "VM.classloader_stats"; 4.48 + } 4.49 + 4.50 + static const char* description() { 4.51 + return "Print statistics about all ClassLoaders."; 4.52 + } 4.53 + 4.54 + static const char* impact() { 4.55 + return "Low"; 4.56 + } 4.57 + 4.58 + virtual void execute(DCmdSource source, TRAPS); 4.59 + 4.60 + static int num_arguments() { 4.61 + return 0; 4.62 + } 4.63 + 4.64 + static const JavaPermission permission() { 4.65 + JavaPermission p = {"java.lang.management.ManagementPermission", 4.66 + "monitor", NULL}; 4.67 + return p; 4.68 + } 4.69 +}; 4.70 + 4.71 + 4.72 +class ClassLoaderStats : public ResourceObj { 4.73 +public: 4.74 + ClassLoaderData* _cld; 4.75 + oop _class_loader; 4.76 + oop _parent; 4.77 + 4.78 + size_t _chunk_sz; 4.79 + size_t _block_sz; 4.80 + uintx _classes_count; 4.81 + 4.82 + size_t _anon_chunk_sz; 4.83 + size_t _anon_block_sz; 4.84 + uintx _anon_classes_count; 4.85 + 4.86 + ClassLoaderStats() : 4.87 + _cld(0), 4.88 + _class_loader(0), 4.89 + _parent(0), 4.90 + _chunk_sz(0), 4.91 + _block_sz(0), 4.92 + _classes_count(0), 4.93 + _anon_block_sz(0), 4.94 + _anon_chunk_sz(0), 4.95 + _anon_classes_count(0) { 4.96 + } 4.97 +}; 4.98 + 4.99 + 4.100 +class ClassLoaderStatsClosure : public CLDClosure { 4.101 +protected: 4.102 + static bool oop_equals(oop const& s1, oop const& s2) { 4.103 + return s1 == s2; 4.104 + } 4.105 + 4.106 + static unsigned oop_hash(oop const& s1) { 4.107 + unsigned hash = (unsigned)((uintptr_t)&s1); 4.108 + return hash ^ (hash >> LogMinObjAlignment); 4.109 + } 4.110 + 4.111 + typedef ResourceHashtable<oop, ClassLoaderStats*, 4.112 + ClassLoaderStatsClosure::oop_hash, ClassLoaderStatsClosure::oop_equals> StatsTable; 4.113 + 4.114 + outputStream* _out; 4.115 + StatsTable* _stats; 4.116 + uintx _total_loaders; 4.117 + uintx _total_classes; 4.118 + size_t _total_chunk_sz; 4.119 + size_t _total_block_sz; 4.120 + 4.121 +public: 4.122 + ClassLoaderStatsClosure(outputStream* out) : 4.123 + _out(out), 4.124 + _total_loaders(0), 4.125 + _total_block_sz(0), 4.126 + _total_chunk_sz(0), 4.127 + _total_classes(0), 4.128 + _stats(new StatsTable()) { 4.129 + } 4.130 + 4.131 + virtual void do_cld(ClassLoaderData* cld); 4.132 + virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls); 4.133 + void print(); 4.134 + 4.135 +private: 4.136 + void addEmptyParents(oop cl); 4.137 +}; 4.138 + 4.139 + 4.140 +class ClassLoaderStatsVMOperation : public VM_Operation { 4.141 + outputStream* _out; 4.142 + 4.143 +public: 4.144 + ClassLoaderStatsVMOperation(outputStream* out) : 4.145 + _out(out) { 4.146 + } 4.147 + 4.148 + VMOp_Type type() const { 4.149 + return VMOp_ClassLoaderStatsOperation; 4.150 + } 4.151 + 4.152 + void doit(); 4.153 +}; 4.154 + 4.155 +#endif // SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
5.1 --- a/src/share/vm/classfile/vmSymbols.hpp Mon Jan 22 14:27:46 2018 -0500 5.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jan 26 09:59:10 2018 -0800 5.3 @@ -573,6 +573,11 @@ 5.4 template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \ 5.5 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") \ 5.6 template(long_long_long_long_void_signature, "(JJJJ)V") \ 5.7 + template(finalizer_histogram_klass, "java/lang/ref/FinalizerHistogram") \ 5.8 + template(void_finalizer_histogram_entry_array_signature, "()[Ljava/lang/ref/FinalizerHistogram$Entry;") \ 5.9 + template(get_finalizer_histogram_name, "getFinalizerHistogram") \ 5.10 + template(finalizer_histogram_entry_name_field, "className") \ 5.11 + template(finalizer_histogram_entry_count_field, "instanceCount") \ 5.12 \ 5.13 template(java_lang_management_MemoryPoolMXBean, "java/lang/management/MemoryPoolMXBean") \ 5.14 template(java_lang_management_MemoryManagerMXBean, "java/lang/management/MemoryManagerMXBean") \
6.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Jan 22 14:27:46 2018 -0500 6.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Fri Jan 26 09:59:10 2018 -0800 6.3 @@ -514,7 +514,15 @@ 6.4 6.5 PerRegionTable* first_prt = _fine_grain_regions[ind]; 6.6 prt->set_collision_list_next(first_prt); 6.7 - _fine_grain_regions[ind] = prt; 6.8 + // The assignment into _fine_grain_regions allows the prt to 6.9 + // start being used concurrently. In addition to 6.10 + // collision_list_next which must be visible (else concurrent 6.11 + // parsing of the list, if any, may fail to see other entries), 6.12 + // the content of the prt must be visible (else for instance 6.13 + // some mark bits may not yet seem cleared or a 'later' update 6.14 + // performed by a concurrent thread could be undone when the 6.15 + // zeroing becomes visible). This requires store ordering. 6.16 + OrderAccess::release_store_ptr((volatile PerRegionTable*)&_fine_grain_regions[ind], prt); 6.17 _n_fine_entries++; 6.18 6.19 if (G1HRRSUseSparseTable) {
7.1 --- a/src/share/vm/memory/metaspace.cpp Mon Jan 22 14:27:46 2018 -0500 7.2 +++ b/src/share/vm/memory/metaspace.cpp Fri Jan 26 09:59:10 2018 -0800 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -154,7 +154,7 @@ 7.11 7.12 // Map a size to a list index assuming that there are lists 7.13 // for special, small, medium, and humongous chunks. 7.14 - static ChunkIndex list_index(size_t size); 7.15 + ChunkIndex list_index(size_t size); 7.16 7.17 // Remove the chunk from its freelist. It is 7.18 // expected to be on one of the _free_chunks[] lists. 7.19 @@ -531,9 +531,8 @@ 7.20 7.21 size_t free_bytes(); 7.22 7.23 - Metachunk* get_new_chunk(size_t word_size, 7.24 - size_t grow_chunks_by_words, 7.25 - size_t medium_chunk_bunch); 7.26 + Metachunk* get_new_chunk(size_t chunk_word_size, 7.27 + size_t suggested_commit_granularity); 7.28 7.29 bool expand_node_by(VirtualSpaceNode* node, 7.30 size_t min_words, 7.31 @@ -687,19 +686,27 @@ 7.32 MediumChunkMultiple = 4 7.33 }; 7.34 7.35 - bool is_class() { return _mdtype == Metaspace::ClassType; } 7.36 + static size_t specialized_chunk_size(bool is_class) { return is_class ? ClassSpecializedChunk : SpecializedChunk; } 7.37 + static size_t small_chunk_size(bool is_class) { return is_class ? ClassSmallChunk : SmallChunk; } 7.38 + static size_t medium_chunk_size(bool is_class) { return is_class ? ClassMediumChunk : MediumChunk; } 7.39 + 7.40 + static size_t smallest_chunk_size(bool is_class) { return specialized_chunk_size(is_class); } 7.41 7.42 // Accessors 7.43 - size_t specialized_chunk_size() { return (size_t) is_class() ? ClassSpecializedChunk : SpecializedChunk; } 7.44 - size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } 7.45 - size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } 7.46 - size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } 7.47 - 7.48 - size_t smallest_chunk_size() { return specialized_chunk_size(); } 7.49 + bool is_class() const { return _mdtype == Metaspace::ClassType; } 7.50 + 7.51 + size_t specialized_chunk_size() const { return specialized_chunk_size(is_class()); } 7.52 + size_t small_chunk_size() const { return small_chunk_size(is_class()); } 7.53 + size_t medium_chunk_size() const { return medium_chunk_size(is_class()); } 7.54 + 7.55 + size_t smallest_chunk_size() const { return smallest_chunk_size(is_class()); } 7.56 + 7.57 + size_t medium_chunk_bunch() const { return medium_chunk_size() * MediumChunkMultiple; } 7.58 7.59 size_t allocated_blocks_words() const { return _allocated_blocks_words; } 7.60 size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; } 7.61 size_t allocated_chunks_words() const { return _allocated_chunks_words; } 7.62 + size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; } 7.63 size_t allocated_chunks_count() const { return _allocated_chunks_count; } 7.64 7.65 bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); } 7.66 @@ -718,10 +725,13 @@ 7.67 // decremented for all the Metachunks in-use by this SpaceManager. 7.68 void dec_total_from_size_metrics(); 7.69 7.70 - // Set the sizes for the initial chunks. 7.71 - void get_initial_chunk_sizes(Metaspace::MetaspaceType type, 7.72 - size_t* chunk_word_size, 7.73 - size_t* class_chunk_word_size); 7.74 + // Adjust the initial chunk size to match one of the fixed chunk list sizes, 7.75 + // or return the unadjusted size if the requested size is humongous. 7.76 + static size_t adjust_initial_chunk_size(size_t requested, bool is_class_space); 7.77 + size_t adjust_initial_chunk_size(size_t requested) const; 7.78 + 7.79 + // Get the initial chunks size for this metaspace type. 7.80 + size_t get_initial_chunk_size(Metaspace::MetaspaceType type) const; 7.81 7.82 size_t sum_capacity_in_chunks_in_use() const; 7.83 size_t sum_used_in_chunks_in_use() const; 7.84 @@ -732,7 +742,7 @@ 7.85 size_t sum_count_in_chunks_in_use(); 7.86 size_t sum_count_in_chunks_in_use(ChunkIndex i); 7.87 7.88 - Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); 7.89 + Metachunk* get_new_chunk(size_t chunk_word_size); 7.90 7.91 // Block allocation and deallocation. 7.92 // Allocates a block from the current chunk 7.93 @@ -1200,7 +1210,7 @@ 7.94 } 7.95 7.96 size_t VirtualSpaceList::free_bytes() { 7.97 - return virtual_space_list()->free_words_in_vs() * BytesPerWord; 7.98 + return current_virtual_space()->free_words_in_vs() * BytesPerWord; 7.99 } 7.100 7.101 // Allocate another meta virtual space and add it to the list. 7.102 @@ -1319,12 +1329,10 @@ 7.103 return false; 7.104 } 7.105 7.106 -Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, 7.107 - size_t grow_chunks_by_words, 7.108 - size_t medium_chunk_bunch) { 7.109 +Metachunk* VirtualSpaceList::get_new_chunk(size_t chunk_word_size, size_t suggested_commit_granularity) { 7.110 7.111 // Allocate a chunk out of the current virtual space. 7.112 - Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); 7.113 + Metachunk* next = current_virtual_space()->get_chunk_vs(chunk_word_size); 7.114 7.115 if (next != NULL) { 7.116 return next; 7.117 @@ -1333,8 +1341,8 @@ 7.118 // The expand amount is currently only determined by the requested sizes 7.119 // and not how much committed memory is left in the current virtual space. 7.120 7.121 - size_t min_word_size = align_size_up(grow_chunks_by_words, Metaspace::commit_alignment_words()); 7.122 - size_t preferred_word_size = align_size_up(medium_chunk_bunch, Metaspace::commit_alignment_words()); 7.123 + size_t min_word_size = align_size_up(chunk_word_size, Metaspace::commit_alignment_words()); 7.124 + size_t preferred_word_size = align_size_up(suggested_commit_granularity, Metaspace::commit_alignment_words()); 7.125 if (min_word_size >= preferred_word_size) { 7.126 // Can happen when humongous chunks are allocated. 7.127 preferred_word_size = min_word_size; 7.128 @@ -1342,7 +1350,7 @@ 7.129 7.130 bool expanded = expand_by(min_word_size, preferred_word_size); 7.131 if (expanded) { 7.132 - next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); 7.133 + next = current_virtual_space()->get_chunk_vs(chunk_word_size); 7.134 assert(next != NULL, "The allocation was expected to succeed after the expansion"); 7.135 } 7.136 7.137 @@ -1744,7 +1752,11 @@ 7.138 st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, 7.139 sum_free_chunks(), sum_free_chunks_count()); 7.140 } 7.141 + 7.142 ChunkList* ChunkManager::free_chunks(ChunkIndex index) { 7.143 + assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, 7.144 + err_msg("Bad index: %d", (int)index)); 7.145 + 7.146 return &_free_chunks[index]; 7.147 } 7.148 7.149 @@ -1856,7 +1868,7 @@ 7.150 } 7.151 7.152 assert((word_size <= chunk->word_size()) || 7.153 - list_index(chunk->word_size() == HumongousIndex), 7.154 + (list_index(chunk->word_size()) == HumongousIndex), 7.155 "Non-humongous variable sized chunk"); 7.156 if (TraceMetadataChunkAllocation) { 7.157 size_t list_count; 7.158 @@ -1883,36 +1895,58 @@ 7.159 7.160 // SpaceManager methods 7.161 7.162 -void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type, 7.163 - size_t* chunk_word_size, 7.164 - size_t* class_chunk_word_size) { 7.165 - switch (type) { 7.166 - case Metaspace::BootMetaspaceType: 7.167 - *chunk_word_size = Metaspace::first_chunk_word_size(); 7.168 - *class_chunk_word_size = Metaspace::first_class_chunk_word_size(); 7.169 - break; 7.170 - case Metaspace::ROMetaspaceType: 7.171 - *chunk_word_size = SharedReadOnlySize / wordSize; 7.172 - *class_chunk_word_size = ClassSpecializedChunk; 7.173 - break; 7.174 - case Metaspace::ReadWriteMetaspaceType: 7.175 - *chunk_word_size = SharedReadWriteSize / wordSize; 7.176 - *class_chunk_word_size = ClassSpecializedChunk; 7.177 - break; 7.178 - case Metaspace::AnonymousMetaspaceType: 7.179 - case Metaspace::ReflectionMetaspaceType: 7.180 - *chunk_word_size = SpecializedChunk; 7.181 - *class_chunk_word_size = ClassSpecializedChunk; 7.182 - break; 7.183 - default: 7.184 - *chunk_word_size = SmallChunk; 7.185 - *class_chunk_word_size = ClassSmallChunk; 7.186 - break; 7.187 +size_t SpaceManager::adjust_initial_chunk_size(size_t requested, bool is_class_space) { 7.188 + size_t chunk_sizes[] = { 7.189 + specialized_chunk_size(is_class_space), 7.190 + small_chunk_size(is_class_space), 7.191 + medium_chunk_size(is_class_space) 7.192 + }; 7.193 + 7.194 + // Adjust up to one of the fixed chunk sizes ... 7.195 + for (size_t i = 0; i < ARRAY_SIZE(chunk_sizes); i++) { 7.196 + if (requested <= chunk_sizes[i]) { 7.197 + return chunk_sizes[i]; 7.198 + } 7.199 } 7.200 - assert(*chunk_word_size != 0 && *class_chunk_word_size != 0, 7.201 - err_msg("Initial chunks sizes bad: data " SIZE_FORMAT 7.202 - " class " SIZE_FORMAT, 7.203 - *chunk_word_size, *class_chunk_word_size)); 7.204 + 7.205 + // ... or return the size as a humongous chunk. 7.206 + return requested; 7.207 +} 7.208 + 7.209 +size_t SpaceManager::adjust_initial_chunk_size(size_t requested) const { 7.210 + return adjust_initial_chunk_size(requested, is_class()); 7.211 +} 7.212 + 7.213 +size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const { 7.214 + size_t requested; 7.215 + 7.216 + if (is_class()) { 7.217 + switch (type) { 7.218 + case Metaspace::BootMetaspaceType: requested = Metaspace::first_class_chunk_word_size(); break; 7.219 + case Metaspace::ROMetaspaceType: requested = ClassSpecializedChunk; break; 7.220 + case Metaspace::ReadWriteMetaspaceType: requested = ClassSpecializedChunk; break; 7.221 + case Metaspace::AnonymousMetaspaceType: requested = ClassSpecializedChunk; break; 7.222 + case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break; 7.223 + default: requested = ClassSmallChunk; break; 7.224 + } 7.225 + } else { 7.226 + switch (type) { 7.227 + case Metaspace::BootMetaspaceType: requested = Metaspace::first_chunk_word_size(); break; 7.228 + case Metaspace::ROMetaspaceType: requested = SharedReadOnlySize / wordSize; break; 7.229 + case Metaspace::ReadWriteMetaspaceType: requested = SharedReadWriteSize / wordSize; break; 7.230 + case Metaspace::AnonymousMetaspaceType: requested = SpecializedChunk; break; 7.231 + case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break; 7.232 + default: requested = SmallChunk; break; 7.233 + } 7.234 + } 7.235 + 7.236 + // Adjust to one of the fixed chunk sizes (unless humongous) 7.237 + const size_t adjusted = adjust_initial_chunk_size(requested); 7.238 + 7.239 + assert(adjusted != 0, err_msg("Incorrect initial chunk size. Requested: " 7.240 + SIZE_FORMAT " adjusted: " SIZE_FORMAT, requested, adjusted)); 7.241 + 7.242 + return adjusted; 7.243 } 7.244 7.245 size_t SpaceManager::sum_free_in_chunks_in_use() const { 7.246 @@ -2102,8 +2136,8 @@ 7.247 } 7.248 7.249 // Get another chunk out of the virtual space 7.250 - size_t grow_chunks_by_words = calc_chunk_size(word_size); 7.251 - Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); 7.252 + size_t chunk_word_size = calc_chunk_size(word_size); 7.253 + Metachunk* next = get_new_chunk(chunk_word_size); 7.254 7.255 MetaWord* mem = NULL; 7.256 7.257 @@ -2328,22 +2362,18 @@ 7.258 } 7.259 7.260 ChunkIndex ChunkManager::list_index(size_t size) { 7.261 - switch (size) { 7.262 - case SpecializedChunk: 7.263 - assert(SpecializedChunk == ClassSpecializedChunk, 7.264 - "Need branch for ClassSpecializedChunk"); 7.265 - return SpecializedIndex; 7.266 - case SmallChunk: 7.267 - case ClassSmallChunk: 7.268 - return SmallIndex; 7.269 - case MediumChunk: 7.270 - case ClassMediumChunk: 7.271 - return MediumIndex; 7.272 - default: 7.273 - assert(size > MediumChunk || size > ClassMediumChunk, 7.274 - "Not a humongous chunk"); 7.275 - return HumongousIndex; 7.276 + if (free_chunks(SpecializedIndex)->size() == size) { 7.277 + return SpecializedIndex; 7.278 } 7.279 + if (free_chunks(SmallIndex)->size() == size) { 7.280 + return SmallIndex; 7.281 + } 7.282 + if (free_chunks(MediumIndex)->size() == size) { 7.283 + return MediumIndex; 7.284 + } 7.285 + 7.286 + assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); 7.287 + return HumongousIndex; 7.288 } 7.289 7.290 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { 7.291 @@ -2365,7 +2395,7 @@ 7.292 7.293 // Find the correct list and and set the current 7.294 // chunk for that list. 7.295 - ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); 7.296 + ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); 7.297 7.298 if (index != HumongousIndex) { 7.299 retire_current_chunk(); 7.300 @@ -2412,14 +2442,12 @@ 7.301 } 7.302 } 7.303 7.304 -Metachunk* SpaceManager::get_new_chunk(size_t word_size, 7.305 - size_t grow_chunks_by_words) { 7.306 +Metachunk* SpaceManager::get_new_chunk(size_t chunk_word_size) { 7.307 // Get a chunk from the chunk freelist 7.308 - Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); 7.309 + Metachunk* next = chunk_manager()->chunk_freelist_allocate(chunk_word_size); 7.310 7.311 if (next == NULL) { 7.312 - next = vs_list()->get_new_chunk(word_size, 7.313 - grow_chunks_by_words, 7.314 + next = vs_list()->get_new_chunk(chunk_word_size, 7.315 medium_chunk_bunch()); 7.316 } 7.317 7.318 @@ -3085,7 +3113,7 @@ 7.319 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); 7.320 assert(using_class_space(), "Must be using class space"); 7.321 _class_space_list = new VirtualSpaceList(rs); 7.322 - _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); 7.323 + _chunk_manager_class = new ChunkManager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); 7.324 7.325 if (!_class_space_list->initialization_succeeded()) { 7.326 vm_exit_during_initialization("Failed to setup compressed class space virtual space list."); 7.327 @@ -3286,66 +3314,62 @@ 7.328 MetaspaceGC::post_initialize(); 7.329 } 7.330 7.331 -Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, 7.332 - size_t chunk_word_size, 7.333 - size_t chunk_bunch) { 7.334 +void Metaspace::initialize_first_chunk(MetaspaceType type, MetadataType mdtype) { 7.335 + Metachunk* chunk = get_initialization_chunk(type, mdtype); 7.336 + if (chunk != NULL) { 7.337 + // Add to this manager's list of chunks in use and current_chunk(). 7.338 + get_space_manager(mdtype)->add_chunk(chunk, true); 7.339 + } 7.340 +} 7.341 + 7.342 +Metachunk* Metaspace::get_initialization_chunk(MetaspaceType type, MetadataType mdtype) { 7.343 + size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type); 7.344 + 7.345 // Get a chunk from the chunk freelist 7.346 Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); 7.347 - if (chunk != NULL) { 7.348 - return chunk; 7.349 + 7.350 + if (chunk == NULL) { 7.351 + chunk = get_space_list(mdtype)->get_new_chunk(chunk_word_size, 7.352 + get_space_manager(mdtype)->medium_chunk_bunch()); 7.353 } 7.354 7.355 - return get_space_list(mdtype)->get_new_chunk(chunk_word_size, chunk_word_size, chunk_bunch); 7.356 + // For dumping shared archive, report error if allocation has failed. 7.357 + if (DumpSharedSpaces && chunk == NULL) { 7.358 + report_insufficient_metaspace(MetaspaceAux::committed_bytes() + chunk_word_size * BytesPerWord); 7.359 + } 7.360 + 7.361 + return chunk; 7.362 } 7.363 7.364 +void Metaspace::verify_global_initialization() { 7.365 + assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); 7.366 + assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized"); 7.367 + 7.368 + if (using_class_space()) { 7.369 + assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); 7.370 + assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized"); 7.371 + } 7.372 +} 7.373 + 7.374 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { 7.375 - 7.376 - assert(space_list() != NULL, 7.377 - "Metadata VirtualSpaceList has not been initialized"); 7.378 - assert(chunk_manager_metadata() != NULL, 7.379 - "Metadata ChunkManager has not been initialized"); 7.380 - 7.381 + verify_global_initialization(); 7.382 + 7.383 + // Allocate SpaceManager for metadata objects. 7.384 _vsm = new SpaceManager(NonClassType, lock); 7.385 - if (_vsm == NULL) { 7.386 - return; 7.387 - } 7.388 - size_t word_size; 7.389 - size_t class_word_size; 7.390 - vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); 7.391 7.392 if (using_class_space()) { 7.393 - assert(class_space_list() != NULL, 7.394 - "Class VirtualSpaceList has not been initialized"); 7.395 - assert(chunk_manager_class() != NULL, 7.396 - "Class ChunkManager has not been initialized"); 7.397 - 7.398 // Allocate SpaceManager for classes. 7.399 _class_vsm = new SpaceManager(ClassType, lock); 7.400 - if (_class_vsm == NULL) { 7.401 - return; 7.402 - } 7.403 } 7.404 7.405 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 7.406 7.407 // Allocate chunk for metadata objects 7.408 - Metachunk* new_chunk = get_initialization_chunk(NonClassType, 7.409 - word_size, 7.410 - vsm()->medium_chunk_bunch()); 7.411 - assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); 7.412 - if (new_chunk != NULL) { 7.413 - // Add to this manager's list of chunks in use and current_chunk(). 7.414 - vsm()->add_chunk(new_chunk, true); 7.415 - } 7.416 + initialize_first_chunk(type, NonClassType); 7.417 7.418 // Allocate chunk for class metadata objects 7.419 if (using_class_space()) { 7.420 - Metachunk* class_chunk = get_initialization_chunk(ClassType, 7.421 - class_word_size, 7.422 - class_vsm()->medium_chunk_bunch()); 7.423 - if (class_chunk != NULL) { 7.424 - class_vsm()->add_chunk(class_chunk, true); 7.425 - } 7.426 + initialize_first_chunk(type, ClassType); 7.427 } 7.428 7.429 _alloc_record_head = NULL; 7.430 @@ -3440,6 +3464,16 @@ 7.431 return capacity_words_slow(mdtype) * BytesPerWord; 7.432 } 7.433 7.434 +size_t Metaspace::allocated_blocks_bytes() const { 7.435 + return vsm()->allocated_blocks_bytes() + 7.436 + (using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0); 7.437 +} 7.438 + 7.439 +size_t Metaspace::allocated_chunks_bytes() const { 7.440 + return vsm()->allocated_chunks_bytes() + 7.441 + (using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0); 7.442 +} 7.443 + 7.444 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { 7.445 if (SafepointSynchronize::is_at_safepoint()) { 7.446 if (DumpSharedSpaces && PrintSharedSpaces) { 7.447 @@ -3772,7 +3806,7 @@ 7.448 // vm_allocation_granularity aligned on Windows. 7.449 size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord)); 7.450 large_size += (os::vm_page_size()/BytesPerWord); 7.451 - vs_list->get_new_chunk(large_size, large_size, 0); 7.452 + vs_list->get_new_chunk(large_size, 0); 7.453 } 7.454 7.455 static void test() { 7.456 @@ -3947,4 +3981,90 @@ 7.457 TestVirtualSpaceNodeTest::test(); 7.458 TestVirtualSpaceNodeTest::test_is_available(); 7.459 } 7.460 + 7.461 +// The following test is placed here instead of a gtest / unittest file 7.462 +// because the ChunkManager class is only available in this file. 7.463 +class SpaceManagerTest : AllStatic { 7.464 + friend void SpaceManager_test_adjust_initial_chunk_size(); 7.465 + 7.466 + static void test_adjust_initial_chunk_size(bool is_class) { 7.467 + const size_t smallest = SpaceManager::smallest_chunk_size(is_class); 7.468 + const size_t normal = SpaceManager::small_chunk_size(is_class); 7.469 + const size_t medium = SpaceManager::medium_chunk_size(is_class); 7.470 + 7.471 +#define test_adjust_initial_chunk_size(value, expected, is_class_value) \ 7.472 + do { \ 7.473 + size_t v = value; \ 7.474 + size_t e = expected; \ 7.475 + assert(SpaceManager::adjust_initial_chunk_size(v, (is_class_value)) == e, \ 7.476 + err_msg("Expected: " SIZE_FORMAT " got: " SIZE_FORMAT, e, v)); \ 7.477 + } while (0) 7.478 + 7.479 + // Smallest (specialized) 7.480 + test_adjust_initial_chunk_size(1, smallest, is_class); 7.481 + test_adjust_initial_chunk_size(smallest - 1, smallest, is_class); 7.482 + test_adjust_initial_chunk_size(smallest, smallest, is_class); 7.483 + 7.484 + // Small 7.485 + test_adjust_initial_chunk_size(smallest + 1, normal, is_class); 7.486 + test_adjust_initial_chunk_size(normal - 1, normal, is_class); 7.487 + test_adjust_initial_chunk_size(normal, normal, is_class); 7.488 + 7.489 + // Medium 7.490 + test_adjust_initial_chunk_size(normal + 1, medium, is_class); 7.491 + test_adjust_initial_chunk_size(medium - 1, medium, is_class); 7.492 + test_adjust_initial_chunk_size(medium, medium, is_class); 7.493 + 7.494 + // Humongous 7.495 + test_adjust_initial_chunk_size(medium + 1, medium + 1, is_class); 7.496 + 7.497 +#undef test_adjust_initial_chunk_size 7.498 + } 7.499 + 7.500 + static void test_adjust_initial_chunk_size() { 7.501 + test_adjust_initial_chunk_size(false); 7.502 + test_adjust_initial_chunk_size(true); 7.503 + } 7.504 +}; 7.505 + 7.506 +void SpaceManager_test_adjust_initial_chunk_size() { 7.507 + SpaceManagerTest::test_adjust_initial_chunk_size(); 7.508 +} 7.509 + 7.510 +// The following test is placed here instead of a gtest / unittest file 7.511 +// because the ChunkManager class is only available in this file. 7.512 +void ChunkManager_test_list_index() { 7.513 + ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); 7.514 + 7.515 + // Test previous bug where a query for a humongous class metachunk, 7.516 + // incorrectly matched the non-class medium metachunk size. 7.517 + { 7.518 + assert(MediumChunk > ClassMediumChunk, "Precondition for test"); 7.519 + 7.520 + ChunkIndex index = manager.list_index(MediumChunk); 7.521 + 7.522 + assert(index == HumongousIndex, 7.523 + err_msg("Requested size is larger than ClassMediumChunk," 7.524 + " so should return HumongousIndex. Got index: %d", (int)index)); 7.525 + } 7.526 + 7.527 + // Check the specified sizes as well. 7.528 + { 7.529 + ChunkIndex index = manager.list_index(ClassSpecializedChunk); 7.530 + assert(index == SpecializedIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 7.531 + } 7.532 + { 7.533 + ChunkIndex index = manager.list_index(ClassSmallChunk); 7.534 + assert(index == SmallIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 7.535 + } 7.536 + { 7.537 + ChunkIndex index = manager.list_index(ClassMediumChunk); 7.538 + assert(index == MediumIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 7.539 + } 7.540 + { 7.541 + ChunkIndex index = manager.list_index(ClassMediumChunk + 1); 7.542 + assert(index == HumongousIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 7.543 + } 7.544 +} 7.545 + 7.546 #endif
8.1 --- a/src/share/vm/memory/metaspace.hpp Mon Jan 22 14:27:46 2018 -0500 8.2 +++ b/src/share/vm/memory/metaspace.hpp Fri Jan 26 09:59:10 2018 -0800 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -104,14 +104,15 @@ 8.11 }; 8.12 8.13 private: 8.14 + static void verify_global_initialization(); 8.15 + 8.16 void initialize(Mutex* lock, MetaspaceType type); 8.17 8.18 - // Get the first chunk for a Metaspace. Used for 8.19 + // Initialize the first chunk for a Metaspace. Used for 8.20 // special cases such as the boot class loader, reflection 8.21 // class loader and anonymous class loader. 8.22 - Metachunk* get_initialization_chunk(MetadataType mdtype, 8.23 - size_t chunk_word_size, 8.24 - size_t chunk_bunch); 8.25 + void initialize_first_chunk(MetaspaceType type, MetadataType mdtype); 8.26 + Metachunk* get_initialization_chunk(MetaspaceType type, MetadataType mdtype); 8.27 8.28 // Align up the word size to the allocation word size 8.29 static size_t align_word_size_up(size_t); 8.30 @@ -138,6 +139,10 @@ 8.31 8.32 SpaceManager* _class_vsm; 8.33 SpaceManager* class_vsm() const { return _class_vsm; } 8.34 + SpaceManager* get_space_manager(MetadataType mdtype) { 8.35 + assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); 8.36 + return mdtype == ClassType ? class_vsm() : vsm(); 8.37 + } 8.38 8.39 // Allocate space for metadata of type mdtype. This is space 8.40 // within a Metachunk and is used by 8.41 @@ -227,6 +232,9 @@ 8.42 size_t used_bytes_slow(MetadataType mdtype) const; 8.43 size_t capacity_bytes_slow(MetadataType mdtype) const; 8.44 8.45 + size_t allocated_blocks_bytes() const; 8.46 + size_t allocated_chunks_bytes() const; 8.47 + 8.48 static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size, 8.49 bool read_only, MetaspaceObj::Type type, TRAPS); 8.50 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
9.1 --- a/src/share/vm/memory/resourceArea.cpp Mon Jan 22 14:27:46 2018 -0500 9.2 +++ b/src/share/vm/memory/resourceArea.cpp Fri Jan 26 09:59:10 2018 -0800 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -27,6 +27,15 @@ 9.11 #include "memory/resourceArea.hpp" 9.12 #include "runtime/mutexLocker.hpp" 9.13 #include "runtime/thread.inline.hpp" 9.14 +#include "services/memTracker.hpp" 9.15 + 9.16 +void ResourceArea::bias_to(MEMFLAGS new_flags) { 9.17 + if (new_flags != _flags) { 9.18 + MemTracker::record_arena_free(_flags); 9.19 + MemTracker::record_new_arena(new_flags); 9.20 + _flags = new_flags; 9.21 + } 9.22 +} 9.23 9.24 //------------------------------ResourceMark----------------------------------- 9.25 debug_only(int ResourceArea::_warned;) // to suppress multiple warnings
10.1 --- a/src/share/vm/memory/resourceArea.hpp Mon Jan 22 14:27:46 2018 -0500 10.2 +++ b/src/share/vm/memory/resourceArea.hpp Fri Jan 26 09:59:10 2018 -0800 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -49,11 +49,11 @@ 10.11 debug_only(static int _warned;) // to suppress multiple warnings 10.12 10.13 public: 10.14 - ResourceArea() : Arena(mtThread) { 10.15 + ResourceArea(MEMFLAGS flags = mtThread) : Arena(flags) { 10.16 debug_only(_nesting = 0;) 10.17 } 10.18 10.19 - ResourceArea(size_t init_size) : Arena(mtThread, init_size) { 10.20 + ResourceArea(size_t init_size, MEMFLAGS flags = mtThread) : Arena(flags, init_size) { 10.21 debug_only(_nesting = 0;); 10.22 } 10.23 10.24 @@ -70,7 +70,11 @@ 10.25 return (char*)Amalloc(size, alloc_failmode); 10.26 } 10.27 10.28 - debug_only(int nesting() const { return _nesting; }); 10.29 + // Bias this resource area to specific memory type 10.30 + // (by default, ResourceArea is tagged as mtThread, per-thread general purpose storage) 10.31 + void bias_to(MEMFLAGS flags); 10.32 + 10.33 + debug_only(int nesting() const { return _nesting; }) 10.34 }; 10.35 10.36
11.1 --- a/src/share/vm/opto/chaitin.cpp Mon Jan 22 14:27:46 2018 -0500 11.2 +++ b/src/share/vm/opto/chaitin.cpp Fri Jan 26 09:59:10 2018 -0800 11.3 @@ -338,8 +338,8 @@ 11.4 _alternate = 0; 11.5 _matcher._allocation_started = true; 11.6 11.7 - ResourceArea split_arena; // Arena for Split local resources 11.8 - ResourceArea live_arena; // Arena for liveness & IFG info 11.9 + ResourceArea split_arena(mtCompiler); // Arena for Split local resources 11.10 + ResourceArea live_arena(mtCompiler); // Arena for liveness & IFG info 11.11 ResourceMark rm(&live_arena); 11.12 11.13 // Need live-ness for the IFG; need the IFG for coalescing. If the
12.1 --- a/src/share/vm/opto/loopopts.cpp Mon Jan 22 14:27:46 2018 -0500 12.2 +++ b/src/share/vm/opto/loopopts.cpp Fri Jan 26 09:59:10 2018 -0800 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -309,6 +309,7 @@ 12.11 } 12.12 return NULL; 12.13 } 12.14 + assert(m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control"); 12.15 } 12.16 12.17 return n_ctrl; 12.18 @@ -609,6 +610,7 @@ 12.19 // Now replace all Phis with CMOV's 12.20 Node *cmov_ctrl = iff->in(0); 12.21 uint flip = (lp->Opcode() == Op_IfTrue); 12.22 + Node_List wq; 12.23 while (1) { 12.24 PhiNode* phi = NULL; 12.25 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { 12.26 @@ -623,17 +625,21 @@ 12.27 if (PrintOpto && VerifyLoopOptimizations) tty->print_cr("CMOV"); 12.28 #endif 12.29 // Move speculative ops 12.30 - for (uint j = 1; j < region->req(); j++) { 12.31 - Node *proj = region->in(j); 12.32 - Node *inp = phi->in(j); 12.33 - if (get_ctrl(inp) == proj) { // Found local op 12.34 + wq.push(phi); 12.35 + while (wq.size() > 0) { 12.36 + Node *n = wq.pop(); 12.37 + for (uint j = 1; j < n->req(); j++) { 12.38 + Node* m = n->in(j); 12.39 + if (m != NULL && !is_dominator(get_ctrl(m), cmov_ctrl)) { 12.40 #ifndef PRODUCT 12.41 - if (PrintOpto && VerifyLoopOptimizations) { 12.42 - tty->print(" speculate: "); 12.43 - inp->dump(); 12.44 + if (PrintOpto && VerifyLoopOptimizations) { 12.45 + tty->print(" speculate: "); 12.46 + m->dump(); 12.47 + } 12.48 +#endif 12.49 + set_ctrl(m, cmov_ctrl); 12.50 + wq.push(m); 12.51 } 12.52 -#endif 12.53 - set_ctrl(inp, cmov_ctrl); 12.54 } 12.55 } 12.56 Node *cmov = CMoveNode::make( C, cmov_ctrl, iff->in(1), phi->in(1+flip), phi->in(2-flip), _igvn.type(phi) );
13.1 --- a/src/share/vm/opto/matcher.cpp Mon Jan 22 14:27:46 2018 -0500 13.2 +++ b/src/share/vm/opto/matcher.cpp Fri Jan 26 09:59:10 2018 -0800 13.3 @@ -79,7 +79,7 @@ 13.4 _register_save_type(register_save_type), 13.5 _ruleName(ruleName), 13.6 _allocation_started(false), 13.7 - _states_arena(Chunk::medium_size), 13.8 + _states_arena(Chunk::medium_size, mtCompiler), 13.9 _visited(&_states_arena), 13.10 _shared(&_states_arena), 13.11 _dontcare(&_states_arena) {
14.1 --- a/src/share/vm/prims/jni.cpp Mon Jan 22 14:27:46 2018 -0500 14.2 +++ b/src/share/vm/prims/jni.cpp Fri Jan 26 09:59:10 2018 -0800 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 14.7 * Copyright (c) 2012 Red Hat, Inc. 14.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.9 * 14.10 @@ -5093,6 +5093,7 @@ 14.11 void TestReserveMemorySpecial_test(); 14.12 void TestVirtualSpace_test(); 14.13 void TestMetaspaceAux_test(); 14.14 +void SpaceManager_test_adjust_initial_chunk_size(); 14.15 void TestMetachunk_test(); 14.16 void TestVirtualSpaceNode_test(); 14.17 void TestNewSize_test(); 14.18 @@ -5105,6 +5106,7 @@ 14.19 void TestBufferingOopClosure_test(); 14.20 void TestCodeCacheRemSet_test(); 14.21 void FreeRegionList_test(); 14.22 +void ChunkManager_test_list_index(); 14.23 #endif 14.24 14.25 void execute_internal_vm_tests() { 14.26 @@ -5137,6 +5139,8 @@ 14.27 run_unit_test(TestOldFreeSpaceCalculation_test()); 14.28 run_unit_test(TestG1BiasedArray_test()); 14.29 run_unit_test(HeapRegionRemSet::test_prt()); 14.30 + run_unit_test(SpaceManager_test_adjust_initial_chunk_size()); 14.31 + run_unit_test(ChunkManager_test_list_index()); 14.32 run_unit_test(TestBufferingOopClosure_test()); 14.33 run_unit_test(TestCodeCacheRemSet_test()); 14.34 if (UseG1GC) {
15.1 --- a/src/share/vm/runtime/thread.cpp Mon Jan 22 14:27:46 2018 -0500 15.2 +++ b/src/share/vm/runtime/thread.cpp Fri Jan 26 09:59:10 2018 -0800 15.3 @@ -3242,6 +3242,9 @@ 15.4 _scanned_nmethod = NULL; 15.5 _compiler = NULL; 15.6 15.7 + // Compiler uses resource area for compilation, let's bias it to mtCompiler 15.8 + resource_area()->bias_to(mtCompiler); 15.9 + 15.10 #ifndef PRODUCT 15.11 _ideal_graph_printer = NULL; 15.12 #endif
16.1 --- a/src/share/vm/runtime/vm_operations.hpp Mon Jan 22 14:27:46 2018 -0500 16.2 +++ b/src/share/vm/runtime/vm_operations.hpp Fri Jan 26 09:59:10 2018 -0800 16.3 @@ -97,6 +97,7 @@ 16.4 template(LinuxDllLoad) \ 16.5 template(RotateGCLog) \ 16.6 template(WhiteBoxOperation) \ 16.7 + template(ClassLoaderStatsOperation) \ 16.8 16.9 class VM_Operation: public CHeapObj<mtInternal> { 16.10 public:
17.1 --- a/src/share/vm/services/diagnosticCommand.cpp Mon Jan 22 14:27:46 2018 -0500 17.2 +++ b/src/share/vm/services/diagnosticCommand.cpp Fri Jan 26 09:59:10 2018 -0800 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -23,14 +23,17 @@ 17.11 */ 17.12 17.13 #include "precompiled.hpp" 17.14 +#include "classfile/classLoaderStats.hpp" 17.15 #include "gc_implementation/shared/vmGCOperations.hpp" 17.16 #include "runtime/javaCalls.hpp" 17.17 +#include "runtime/os.hpp" 17.18 #include "services/diagnosticArgument.hpp" 17.19 #include "services/diagnosticCommand.hpp" 17.20 #include "services/diagnosticFramework.hpp" 17.21 #include "services/heapDumper.hpp" 17.22 #include "services/management.hpp" 17.23 #include "utilities/macros.hpp" 17.24 +#include "oops/objArrayOop.hpp" 17.25 17.26 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 17.27 17.28 @@ -46,9 +49,12 @@ 17.29 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false)); 17.30 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false)); 17.31 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false)); 17.32 + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false)); 17.33 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false)); 17.34 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false)); 17.35 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false)); 17.36 + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false)); 17.37 + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false)); 17.38 #if INCLUDE_SERVICES // Heap dumping/inspection supported 17.39 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); 17.40 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false)); 17.41 @@ -56,6 +62,7 @@ 17.42 #endif // INCLUDE_SERVICES 17.43 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false)); 17.44 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false)); 17.45 + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false)); 17.46 17.47 // Enhanced JMX Agent Support 17.48 // These commands won't be exported via the DiagnosticCommandMBean until an 17.49 @@ -273,6 +280,60 @@ 17.50 vmSymbols::void_method_signature(), CHECK); 17.51 } 17.52 17.53 +void HeapInfoDCmd::execute(DCmdSource source, TRAPS) { 17.54 + Universe::heap()->print_on(output()); 17.55 +} 17.56 + 17.57 +void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) { 17.58 + ResourceMark rm; 17.59 + 17.60 + 17.61 + Klass* k = SystemDictionary::resolve_or_null( 17.62 + vmSymbols::finalizer_histogram_klass(), THREAD); 17.63 + assert(k != NULL, "FinalizerHistogram class is not accessible"); 17.64 + 17.65 + instanceKlassHandle klass(THREAD, k); 17.66 + JavaValue result(T_ARRAY); 17.67 + 17.68 + // We are calling lang.ref.FinalizerHistogram.getFinalizerHistogram() method 17.69 + // and expect it to return array of FinalizerHistogramEntry as Object[] 17.70 + 17.71 + JavaCalls::call_static(&result, klass, 17.72 + vmSymbols::get_finalizer_histogram_name(), 17.73 + vmSymbols::void_finalizer_histogram_entry_array_signature(), CHECK); 17.74 + 17.75 + objArrayOop result_oop = (objArrayOop) result.get_jobject(); 17.76 + if (result_oop->length() == 0) { 17.77 + output()->print_cr("No instances waiting for finalization found"); 17.78 + return; 17.79 + } 17.80 + 17.81 + oop foop = result_oop->obj_at(0); 17.82 + InstanceKlass* ik = InstanceKlass::cast(foop->klass()); 17.83 + 17.84 + fieldDescriptor count_fd, name_fd; 17.85 + 17.86 + Klass* count_res = ik->find_field( 17.87 + vmSymbols::finalizer_histogram_entry_count_field(), vmSymbols::int_signature(), &count_fd); 17.88 + 17.89 + Klass* name_res = ik->find_field( 17.90 + vmSymbols::finalizer_histogram_entry_name_field(), vmSymbols::string_signature(), &name_fd); 17.91 + 17.92 + assert(count_res != NULL && name_res != NULL, "Unexpected layout of FinalizerHistogramEntry"); 17.93 + 17.94 + output()->print_cr("Unreachable instances waiting for finalization"); 17.95 + output()->print_cr("#instances class name"); 17.96 + output()->print_cr("-----------------------"); 17.97 + 17.98 + for (int i = 0; i < result_oop->length(); ++i) { 17.99 + oop element_oop = result_oop->obj_at(i); 17.100 + oop str_oop = element_oop->obj_field(name_fd.offset()); 17.101 + char *name = java_lang_String::as_utf8_string(str_oop); 17.102 + int count = element_oop->int_field(count_fd.offset()); 17.103 + output()->print_cr("%10d %s", count, name); 17.104 + } 17.105 +} 17.106 + 17.107 #if INCLUDE_SERVICES // Heap dumping/inspection supported 17.108 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : 17.109 DCmdWithParser(output, heap), 17.110 @@ -619,8 +680,7 @@ 17.111 } 17.112 17.113 JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) : 17.114 - DCmd(output, heap_allocated) 17.115 -{ 17.116 + DCmd(output, heap_allocated) { 17.117 // do nothing 17.118 } 17.119 17.120 @@ -641,7 +701,6 @@ 17.121 JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK); 17.122 } 17.123 17.124 - 17.125 void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) { 17.126 ResourceMark rm(THREAD); 17.127 HandleMark hm(THREAD); 17.128 @@ -659,6 +718,16 @@ 17.129 JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); 17.130 } 17.131 17.132 +VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) : 17.133 + DCmd(output, heap_allocated) { 17.134 + // do nothing 17.135 +} 17.136 + 17.137 +void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) { 17.138 + os::print_dll_info(output()); 17.139 + output()->cr(); 17.140 +} 17.141 + 17.142 void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) { 17.143 if (UseGCLogFileRotation) { 17.144 VM_RotateGCLog rotateop(output());
18.1 --- a/src/share/vm/services/diagnosticCommand.hpp Mon Jan 22 14:27:46 2018 -0500 18.2 +++ b/src/share/vm/services/diagnosticCommand.hpp Fri Jan 26 09:59:10 2018 -0800 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -132,6 +132,29 @@ 18.11 virtual void execute(DCmdSource source, TRAPS); 18.12 }; 18.13 18.14 +class VMDynamicLibrariesDCmd : public DCmd { 18.15 +public: 18.16 + VMDynamicLibrariesDCmd(outputStream* output, bool heap); 18.17 + static const char* name() { 18.18 + return "VM.dynlibs"; 18.19 + } 18.20 + static const char* description() { 18.21 + return "Print loaded dynamic libraries."; 18.22 + } 18.23 + static const char* impact() { 18.24 + return "Low"; 18.25 + } 18.26 + static const JavaPermission permission() { 18.27 + JavaPermission p = {"java.lang.management.ManagementPermission", 18.28 + "monitor", NULL}; 18.29 + return p; 18.30 + } 18.31 + static int num_arguments() { 18.32 + return 0; 18.33 + }; 18.34 + virtual void execute(DCmdSource source, TRAPS); 18.35 +}; 18.36 + 18.37 class VMUptimeDCmd : public DCmdWithParser { 18.38 protected: 18.39 DCmdArgument<bool> _date; 18.40 @@ -176,6 +199,46 @@ 18.41 virtual void execute(DCmdSource source, TRAPS); 18.42 }; 18.43 18.44 +class HeapInfoDCmd : public DCmd { 18.45 +public: 18.46 + HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 18.47 + static const char* name() { return "GC.heap_info"; } 18.48 + static const char* description() { 18.49 + return "Provide generic Java heap information."; 18.50 + } 18.51 + static const char* impact() { 18.52 + return "Medium"; 18.53 + } 18.54 + static int num_arguments() { return 0; } 18.55 + static const JavaPermission permission() { 18.56 + JavaPermission p = {"java.lang.management.ManagementPermission", 18.57 + "monitor", NULL}; 18.58 + return p; 18.59 + } 18.60 + 18.61 + virtual void execute(DCmdSource source, TRAPS); 18.62 +}; 18.63 + 18.64 +class FinalizerInfoDCmd : public DCmd { 18.65 +public: 18.66 + FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 18.67 + static const char* name() { return "GC.finalizer_info"; } 18.68 + static const char* description() { 18.69 + return "Provide information about Java finalization queue."; 18.70 + } 18.71 + static const char* impact() { 18.72 + return "Medium"; 18.73 + } 18.74 + static int num_arguments() { return 0; } 18.75 + static const JavaPermission permission() { 18.76 + JavaPermission p = {"java.lang.management.ManagementPermission", 18.77 + "monitor", NULL}; 18.78 + return p; 18.79 + } 18.80 + 18.81 + virtual void execute(DCmdSource source, TRAPS); 18.82 +}; 18.83 + 18.84 #if INCLUDE_SERVICES // Heap dumping supported 18.85 // See also: dump_heap in attachListener.cpp 18.86 class HeapDumpDCmd : public DCmdWithParser {
19.1 --- a/src/share/vm/services/mallocSiteTable.cpp Mon Jan 22 14:27:46 2018 -0500 19.2 +++ b/src/share/vm/services/mallocSiteTable.cpp Fri Jan 26 09:59:10 2018 -0800 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -97,7 +97,7 @@ 19.11 19.12 // Instantiate hash entry for hashtable entry allocation callsite 19.13 MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site) 19.14 - MallocSiteHashtableEntry(*stack); 19.15 + MallocSiteHashtableEntry(*stack, mtNMT); 19.16 19.17 // Add the allocation site to hashtable. 19.18 int index = hash_to_index(stack->hash()); 19.19 @@ -134,7 +134,8 @@ 19.20 * Under any of above circumstances, caller should handle the situation. 19.21 */ 19.22 MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, 19.23 - size_t* pos_idx) { 19.24 + size_t* pos_idx, MEMFLAGS flags) { 19.25 + assert(flags != mtNone, "Should have a real memory type"); 19.26 int index = hash_to_index(key.hash()); 19.27 assert(index >= 0, "Negative index"); 19.28 *bucket_idx = (size_t)index; 19.29 @@ -142,7 +143,7 @@ 19.30 19.31 // First entry for this hash bucket 19.32 if (_table[index] == NULL) { 19.33 - MallocSiteHashtableEntry* entry = new_entry(key); 19.34 + MallocSiteHashtableEntry* entry = new_entry(key, flags); 19.35 // OOM check 19.36 if (entry == NULL) return NULL; 19.37 19.38 @@ -157,13 +158,12 @@ 19.39 MallocSiteHashtableEntry* head = _table[index]; 19.40 while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { 19.41 MallocSite* site = head->data(); 19.42 - if (site->equals(key)) { 19.43 - // found matched entry 19.44 + if (site->flags() == flags && site->equals(key)) { 19.45 return head->data(); 19.46 } 19.47 19.48 if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) { 19.49 - MallocSiteHashtableEntry* entry = new_entry(key); 19.50 + MallocSiteHashtableEntry* entry = new_entry(key, flags); 19.51 // OOM check 19.52 if (entry == NULL) return NULL; 19.53 if (head->atomic_insert(entry)) { 19.54 @@ -192,10 +192,10 @@ 19.55 // Allocates MallocSiteHashtableEntry object. Special call stack 19.56 // (pre-installed allocation site) has to be used to avoid infinite 19.57 // recursion. 19.58 -MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key) { 19.59 +MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key, MEMFLAGS flags) { 19.60 void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT, 19.61 *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL); 19.62 - return ::new (p) MallocSiteHashtableEntry(key); 19.63 + return ::new (p) MallocSiteHashtableEntry(key, flags); 19.64 } 19.65 19.66 void MallocSiteTable::reset() {
20.1 --- a/src/share/vm/services/mallocSiteTable.hpp Mon Jan 22 14:27:46 2018 -0500 20.2 +++ b/src/share/vm/services/mallocSiteTable.hpp Fri Jan 26 09:59:10 2018 -0800 20.3 @@ -1,5 +1,5 @@ 20.4 /* 20.5 - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 20.6 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 20.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 * 20.9 * This code is free software; you can redistribute it and/or modify it 20.10 @@ -37,12 +37,16 @@ 20.11 // MallocSite represents a code path that eventually calls 20.12 // os::malloc() to allocate memory 20.13 class MallocSite : public AllocationSite<MemoryCounter> { 20.14 + private: 20.15 + MEMFLAGS _flags; 20.16 + 20.17 public: 20.18 MallocSite() : 20.19 - AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK) { } 20.20 + AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK), _flags(mtNone) {} 20.21 20.22 - MallocSite(const NativeCallStack& stack) : 20.23 - AllocationSite<MemoryCounter>(stack) { } 20.24 + MallocSite(const NativeCallStack& stack, MEMFLAGS flags) : 20.25 + AllocationSite<MemoryCounter>(stack), _flags(flags) {} 20.26 + 20.27 20.28 void allocate(size_t size) { data()->allocate(size); } 20.29 void deallocate(size_t size) { data()->deallocate(size); } 20.30 @@ -51,6 +55,7 @@ 20.31 size_t size() const { return peek()->size(); } 20.32 // The number of calls were made 20.33 size_t count() const { return peek()->count(); } 20.34 + MEMFLAGS flags() const { return (MEMFLAGS)_flags; } 20.35 }; 20.36 20.37 // Malloc site hashtable entry 20.38 @@ -62,8 +67,10 @@ 20.39 public: 20.40 MallocSiteHashtableEntry() : _next(NULL) { } 20.41 20.42 - MallocSiteHashtableEntry(NativeCallStack stack): 20.43 - _malloc_site(stack), _next(NULL) { } 20.44 + MallocSiteHashtableEntry(NativeCallStack stack, MEMFLAGS flags): 20.45 + _malloc_site(stack, flags), _next(NULL) { 20.46 + assert(flags != mtNone, "Expect a real memory type"); 20.47 + } 20.48 20.49 inline const MallocSiteHashtableEntry* next() const { 20.50 return _next; 20.51 @@ -198,11 +205,11 @@ 20.52 // 1. out of memory 20.53 // 2. overflow hash bucket 20.54 static inline bool allocation_at(const NativeCallStack& stack, size_t size, 20.55 - size_t* bucket_idx, size_t* pos_idx) { 20.56 + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) { 20.57 AccessLock locker(&_access_count); 20.58 if (locker.sharedLock()) { 20.59 NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) 20.60 - MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx); 20.61 + MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx, flags); 20.62 if (site != NULL) site->allocate(size); 20.63 return site != NULL; 20.64 } 20.65 @@ -228,13 +235,13 @@ 20.66 static bool walk_malloc_site(MallocSiteWalker* walker); 20.67 20.68 private: 20.69 - static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key); 20.70 + static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key, MEMFLAGS flags); 20.71 static void reset(); 20.72 20.73 // Delete a bucket linked list 20.74 static void delete_linked_list(MallocSiteHashtableEntry* head); 20.75 20.76 - static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx); 20.77 + static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags); 20.78 static MallocSite* malloc_site(size_t bucket_idx, size_t pos_idx); 20.79 static bool walk(MallocSiteWalker* walker); 20.80
21.1 --- a/src/share/vm/services/mallocTracker.cpp Mon Jan 22 14:27:46 2018 -0500 21.2 +++ b/src/share/vm/services/mallocTracker.cpp Fri Jan 26 09:59:10 2018 -0800 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 21.6 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -78,8 +78,8 @@ 21.11 } 21.12 21.13 bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size, 21.14 - size_t* bucket_idx, size_t* pos_idx) const { 21.15 - bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx); 21.16 + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const { 21.17 + bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags); 21.18 21.19 // Something went wrong, could be OOM or overflow malloc site table. 21.20 // We want to keep tracking data under OOM circumstance, so transition to
22.1 --- a/src/share/vm/services/mallocTracker.hpp Mon Jan 22 14:27:46 2018 -0500 22.2 +++ b/src/share/vm/services/mallocTracker.hpp Fri Jan 26 09:59:10 2018 -0800 22.3 @@ -268,7 +268,7 @@ 22.4 if (level == NMT_detail) { 22.5 size_t bucket_idx; 22.6 size_t pos_idx; 22.7 - if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) { 22.8 + if (record_malloc_site(stack, size, &bucket_idx, &pos_idx, flags)) { 22.9 assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index"); 22.10 assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index"); 22.11 _bucket_idx = bucket_idx; 22.12 @@ -292,7 +292,7 @@ 22.13 _size = size; 22.14 } 22.15 bool record_malloc_site(const NativeCallStack& stack, size_t size, 22.16 - size_t* bucket_idx, size_t* pos_idx) const; 22.17 + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const; 22.18 }; 22.19 22.20
23.1 --- a/src/share/vm/services/memBaseline.cpp Mon Jan 22 14:27:46 2018 -0500 23.2 +++ b/src/share/vm/services/memBaseline.cpp Fri Jan 26 09:59:10 2018 -0800 23.3 @@ -1,5 +1,5 @@ 23.4 /* 23.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 23.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 23.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 * 23.9 * This code is free software; you can redistribute it and/or modify it 23.10 @@ -59,6 +59,15 @@ 23.11 return s1.call_stack()->compare(*s2.call_stack()); 23.12 } 23.13 23.14 +// Sort into allocation site addresses and memory type order for baseline comparison 23.15 +int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) { 23.16 + int res = compare_malloc_site(s1, s2); 23.17 + if (res == 0) { 23.18 + res = (int)(s1.flags() - s2.flags()); 23.19 + } 23.20 + 23.21 + return res; 23.22 +} 23.23 23.24 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1, 23.25 const VirtualMemoryAllocationSite& s2) { 23.26 @@ -225,6 +234,9 @@ 23.27 case by_site: 23.28 malloc_sites_to_allocation_site_order(); 23.29 break; 23.30 + case by_site_and_type: 23.31 + malloc_sites_to_allocation_site_and_type_order(); 23.32 + break; 23.33 case by_address: 23.34 default: 23.35 ShouldNotReachHere(); 23.36 @@ -263,7 +275,7 @@ 23.37 } 23.38 23.39 void MemBaseline::malloc_sites_to_allocation_site_order() { 23.40 - if (_malloc_sites_order != by_site) { 23.41 + if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) { 23.42 SortedLinkedList<MallocSite, compare_malloc_site> tmp; 23.43 // Add malloc sites to sorted linked list to sort into site (address) order 23.44 tmp.move(&_malloc_sites); 23.45 @@ -273,6 +285,17 @@ 23.46 } 23.47 } 23.48 23.49 +void MemBaseline::malloc_sites_to_allocation_site_and_type_order() { 23.50 + if (_malloc_sites_order != by_site_and_type) { 23.51 + SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp; 23.52 + // Add malloc sites to sorted linked list to sort into site (address) order 23.53 + tmp.move(&_malloc_sites); 23.54 + _malloc_sites.set_head(tmp.head()); 23.55 + tmp.set_head(NULL); 23.56 + _malloc_sites_order = by_site_and_type; 23.57 + } 23.58 +} 23.59 + 23.60 void MemBaseline::virtual_memory_sites_to_size_order() { 23.61 if (_virtual_memory_sites_order != by_size) { 23.62 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
24.1 --- a/src/share/vm/services/memBaseline.hpp Mon Jan 22 14:27:46 2018 -0500 24.2 +++ b/src/share/vm/services/memBaseline.hpp Fri Jan 26 09:59:10 2018 -0800 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 24.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 * 24.9 * This code is free software; you can redistribute it and/or modify it 24.10 @@ -55,9 +55,10 @@ 24.11 }; 24.12 24.13 enum SortingOrder { 24.14 - by_address, // by memory address 24.15 - by_size, // by memory size 24.16 - by_site // by call site where the memory is allocated from 24.17 + by_address, // by memory address 24.18 + by_size, // by memory size 24.19 + by_site, // by call site where the memory is allocated from 24.20 + by_site_and_type // by call site and memory type 24.21 }; 24.22 24.23 private: 24.24 @@ -188,6 +189,8 @@ 24.25 void malloc_sites_to_size_order(); 24.26 // Sort allocation sites in call site address order 24.27 void malloc_sites_to_allocation_site_order(); 24.28 + // Sort allocation sites in call site address and memory type order 24.29 + void malloc_sites_to_allocation_site_and_type_order(); 24.30 24.31 // Sort allocation sites in reserved size order 24.32 void virtual_memory_sites_to_size_order();
25.1 --- a/src/share/vm/services/memReporter.cpp Mon Jan 22 14:27:46 2018 -0500 25.2 +++ b/src/share/vm/services/memReporter.cpp Fri Jan 26 09:59:10 2018 -0800 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 25.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 25.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 * 25.9 * This code is free software; you can redistribute it and/or modify it 25.10 @@ -43,11 +43,16 @@ 25.11 amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); 25.12 } 25.13 25.14 -void MemReporterBase::print_malloc(size_t amount, size_t count) const { 25.15 +void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) const { 25.16 const char* scale = current_scale(); 25.17 outputStream* out = output(); 25.18 - out->print("(malloc=" SIZE_FORMAT "%s", 25.19 - amount_in_current_scale(amount), scale); 25.20 + if (flag != mtNone) { 25.21 + out->print("(malloc=" SIZE_FORMAT "%s type=%s", 25.22 + amount_in_current_scale(amount), scale, NMTUtil::flag_to_name(flag)); 25.23 + } else { 25.24 + out->print("(malloc=" SIZE_FORMAT "%s", 25.25 + amount_in_current_scale(amount), scale); 25.26 + } 25.27 25.28 if (count > 0) { 25.29 out->print(" #" SIZE_FORMAT "", count); 25.30 @@ -200,7 +205,10 @@ 25.31 const NativeCallStack* stack = malloc_site->call_stack(); 25.32 stack->print_on(out); 25.33 out->print("%29s", " "); 25.34 - print_malloc(malloc_site->size(), malloc_site->count()); 25.35 + MEMFLAGS flag = malloc_site->flags(); 25.36 + assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone, 25.37 + "Must have a valid memory type"); 25.38 + print_malloc(malloc_site->size(), malloc_site->count(),flag); 25.39 out->print_cr("\n"); 25.40 } 25.41 } 25.42 @@ -304,11 +312,16 @@ 25.43 } 25.44 25.45 void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t current_count, 25.46 - size_t early_amount, size_t early_count) const { 25.47 + size_t early_amount, size_t early_count, MEMFLAGS flags) const { 25.48 const char* scale = current_scale(); 25.49 outputStream* out = output(); 25.50 25.51 out->print("malloc=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale); 25.52 + // Report type only if it is valid 25.53 + if (flags != mtNone) { 25.54 + out->print(" type=%s", NMTUtil::flag_to_name(flags)); 25.55 + } 25.56 + 25.57 long amount_diff = diff_in_current_scale(current_amount, early_amount); 25.58 if (amount_diff != 0) { 25.59 out->print(" %+ld%s", amount_diff, scale); 25.60 @@ -437,7 +450,7 @@ 25.61 diff_in_current_scale(current_malloc_amount, early_malloc_amount) != 0) { 25.62 out->print("%28s(", " "); 25.63 print_malloc_diff(current_malloc_amount, (flag == mtChunk) ? 0 : current_malloc->malloc_count(), 25.64 - early_malloc_amount, early_malloc->malloc_count()); 25.65 + early_malloc_amount, early_malloc->malloc_count(), mtNone); 25.66 out->print_cr(")"); 25.67 } 25.68 25.69 @@ -485,8 +498,8 @@ 25.70 } 25.71 25.72 void MemDetailDiffReporter::diff_malloc_sites() const { 25.73 - MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site); 25.74 - MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site); 25.75 + MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site_and_type); 25.76 + MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site_and_type); 25.77 25.78 const MallocSite* early_site = early_itr.next(); 25.79 const MallocSite* current_site = current_itr.next(); 25.80 @@ -549,22 +562,23 @@ 25.81 25.82 void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const { 25.83 diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(), 25.84 - 0, 0); 25.85 + 0, 0, malloc_site->flags()); 25.86 } 25.87 25.88 void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const { 25.89 diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(), 25.90 - malloc_site->count()); 25.91 + malloc_site->count(), malloc_site->flags()); 25.92 } 25.93 25.94 void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early, 25.95 const MallocSite* current) const { 25.96 + assert(early->flags() == current->flags(), "Must be the same memory type"); 25.97 diff_malloc_site(current->call_stack(), current->size(), current->count(), 25.98 - early->size(), early->count()); 25.99 + early->size(), early->count(), early->flags()); 25.100 } 25.101 25.102 void MemDetailDiffReporter::diff_malloc_site(const NativeCallStack* stack, size_t current_size, 25.103 - size_t current_count, size_t early_size, size_t early_count) const { 25.104 + size_t current_count, size_t early_size, size_t early_count, MEMFLAGS flags) const { 25.105 outputStream* out = output(); 25.106 25.107 assert(stack != NULL, "NULL stack"); 25.108 @@ -576,7 +590,7 @@ 25.109 stack->print_on(out); 25.110 out->print("%28s (", " "); 25.111 print_malloc_diff(current_size, current_count, 25.112 - early_size, early_count); 25.113 + early_size, early_count, flags); 25.114 25.115 out->print_cr(")\n"); 25.116 }
26.1 --- a/src/share/vm/services/memReporter.hpp Mon Jan 22 14:27:46 2018 -0500 26.2 +++ b/src/share/vm/services/memReporter.hpp Fri Jan 26 09:59:10 2018 -0800 26.3 @@ -1,5 +1,5 @@ 26.4 /* 26.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 26.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 26.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.8 * 26.9 * This code is free software; you can redistribute it and/or modify it 26.10 @@ -76,7 +76,7 @@ 26.11 26.12 // Print summary total, malloc and virtual memory 26.13 void print_total(size_t reserved, size_t committed) const; 26.14 - void print_malloc(size_t amount, size_t count) const; 26.15 + void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const; 26.16 void print_virtual_memory(size_t reserved, size_t committed) const; 26.17 26.18 void print_malloc_line(size_t amount, size_t count) const; 26.19 @@ -174,7 +174,7 @@ 26.20 26.21 protected: 26.22 void print_malloc_diff(size_t current_amount, size_t current_count, 26.23 - size_t early_amount, size_t early_count) const; 26.24 + size_t early_amount, size_t early_count, MEMFLAGS flags) const; 26.25 void print_virtual_memory_diff(size_t current_reserved, size_t current_committed, 26.26 size_t early_reserved, size_t early_committed) const; 26.27 void print_arena_diff(size_t current_amount, size_t current_count, 26.28 @@ -216,7 +216,7 @@ 26.29 const VirtualMemoryAllocationSite* current) const; 26.30 26.31 void diff_malloc_site(const NativeCallStack* stack, size_t current_size, 26.32 - size_t currrent_count, size_t early_size, size_t early_count) const; 26.33 + size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const; 26.34 void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, 26.35 size_t current_committed, size_t early_reserved, size_t early_committed) const; 26.36 };
27.1 --- a/src/share/vm/utilities/debug.cpp Mon Jan 22 14:27:46 2018 -0500 27.2 +++ b/src/share/vm/utilities/debug.cpp Fri Jan 26 09:59:10 2018 -0800 27.3 @@ -1,5 +1,5 @@ 27.4 /* 27.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 27.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 27.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.8 * 27.9 * This code is free software; you can redistribute it and/or modify it 27.10 @@ -315,6 +315,14 @@ 27.11 } 27.12 } 27.13 27.14 +void report_insufficient_metaspace(size_t required_size) { 27.15 + warning("\nThe MaxMetaspaceSize of " SIZE_FORMAT " bytes is not large enough.\n" 27.16 + "Either don't specify the -XX:MaxMetaspaceSize=<size>\n" 27.17 + "or increase the size to at least " SIZE_FORMAT ".\n", 27.18 + MaxMetaspaceSize, required_size); 27.19 + exit(2); 27.20 +} 27.21 + 27.22 static bool error_reported = false; 27.23 27.24 // call this when the VM is dying--it might loosen some asserts
28.1 --- a/src/share/vm/utilities/debug.hpp Mon Jan 22 14:27:46 2018 -0500 28.2 +++ b/src/share/vm/utilities/debug.hpp Fri Jan 26 09:59:10 2018 -0800 28.3 @@ -1,5 +1,5 @@ 28.4 /* 28.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 28.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 * 28.9 * This code is free software; you can redistribute it and/or modify it 28.10 @@ -222,6 +222,7 @@ 28.11 void report_should_not_reach_here(const char* file, int line); 28.12 void report_unimplemented(const char* file, int line); 28.13 void report_untested(const char* file, int line, const char* message); 28.14 +void report_insufficient_metaspace(size_t required_size); 28.15 28.16 void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2); 28.17
29.1 --- a/test/TEST.groups Mon Jan 22 14:27:46 2018 -0500 29.2 +++ b/test/TEST.groups Fri Jan 26 09:59:10 2018 -0800 29.3 @@ -96,6 +96,7 @@ 29.4 runtime/XCheckJniJsig/XCheckJSig.java \ 29.5 serviceability/attach/AttachWithStalePidFile.java \ 29.6 serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \ 29.7 + serviceability/dcmd/DynLibDcmdTest.java \ 29.8 testlibrary_tests/ 29.9 29.10
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/compiler/loopopts/TestCMovSplitThruPhi.java Fri Jan 26 09:59:10 2018 -0800 30.3 @@ -0,0 +1,67 @@ 30.4 +/* 30.5 + * Copyright (c) 2017, Red Hat, Inc. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.23 + * or visit www.oracle.com if you need additional information or have any 30.24 + * questions. 30.25 + */ 30.26 + 30.27 +/** 30.28 + * @test 30.29 + * @bug 8187822 30.30 + * @summary C2 conditonal move optimization might create broken graph 30.31 + * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestCMovSplitThruPhi::not_inlined -XX:CompileOnly=TestCMovSplitThruPhi::test -XX:-LoopUnswitching TestCMovSplitThruPhi 30.32 + * 30.33 + */ 30.34 + 30.35 +public class TestCMovSplitThruPhi { 30.36 + static int f; 30.37 + 30.38 + static int test(boolean flag1, boolean flag2, boolean flag3, boolean flag4) { 30.39 + int v3 = 0; 30.40 + if (flag4) { 30.41 + for (int i = 0; i < 10; i++) { 30.42 + int v1 = 0; 30.43 + if (flag1) { 30.44 + v1 = not_inlined(); 30.45 + } 30.46 + // AddI below will be candidate for split through Phi 30.47 + int v2 = v1; 30.48 + if (flag2) { 30.49 + v2 = f + v1; 30.50 + } 30.51 + // test above will be converted to CMovI 30.52 + if (flag3) { 30.53 + v3 = v2 * 2; 30.54 + break; 30.55 + } 30.56 + } 30.57 + } 30.58 + return v3; 30.59 + } 30.60 + 30.61 + private static int not_inlined() { 30.62 + return 0; 30.63 + } 30.64 + 30.65 + public static void main(String[] args) { 30.66 + for (int i = 0; i < 20000; i++) { 30.67 + test((i % 2) == 0, (i % 2) == 0, (i % 100) == 1, (i % 1000) == 1); 30.68 + } 30.69 + } 30.70 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/serviceability/dcmd/ClassLoaderStatsTest.java Fri Jan 26 09:59:10 2018 -0800 31.3 @@ -0,0 +1,155 @@ 31.4 +/* 31.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.23 + * or visit www.oracle.com if you need additional information or have any 31.24 + * questions. 31.25 + */ 31.26 + 31.27 +/* 31.28 + * @test 31.29 + * 31.30 + * @build ClassLoaderStatsTest DcmdUtil 31.31 + * @run main ClassLoaderStatsTest 31.32 + */ 31.33 + 31.34 +import java.io.BufferedReader; 31.35 +import java.io.File; 31.36 +import java.io.FileInputStream; 31.37 +import java.io.IOException; 31.38 +import java.io.StringReader; 31.39 +import java.nio.ByteBuffer; 31.40 +import java.nio.channels.FileChannel; 31.41 +import java.util.regex.Matcher; 31.42 +import java.util.regex.Pattern; 31.43 + 31.44 +public class ClassLoaderStatsTest { 31.45 + 31.46 + // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type 31.47 + // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1 31.48 + // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader 31.49 + // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader 31.50 + // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader 31.51 + // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader 31.52 + // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader> 31.53 + // 455 1210368 672848 + unsafe anonymous classes 31.54 + // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader 31.55 + // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader 31.56 + // ... 31.57 + 31.58 + static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)"); 31.59 + static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*"); 31.60 + 31.61 + public static DummyClassLoader dummyloader; 31.62 + 31.63 + public static void main(String arg[]) throws Exception { 31.64 + 31.65 + // create a classloader and load our special class 31.66 + dummyloader = new DummyClassLoader(); 31.67 + Class<?> c = Class.forName("TestClass", true, dummyloader); 31.68 + if (c.getClassLoader() != dummyloader) { 31.69 + throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader()); 31.70 + } 31.71 + 31.72 + String result = DcmdUtil.executeDcmd("VM.classloader_stats"); 31.73 + BufferedReader r = new BufferedReader(new StringReader(result)); 31.74 + String line; 31.75 + while((line = r.readLine()) != null) { 31.76 + Matcher m = clLine.matcher(line); 31.77 + if (m.matches()) { 31.78 + // verify that DummyClassLoader has loaded 1 class and 1 anonymous class 31.79 + if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) { 31.80 + System.out.println("line: " + line); 31.81 + if (!m.group(1).equals("1")) { 31.82 + throw new Exception("Should have loaded 1 class: " + line); 31.83 + } 31.84 + checkPositiveInt(m.group(2)); 31.85 + checkPositiveInt(m.group(3)); 31.86 + 31.87 + String next = r.readLine(); 31.88 + System.out.println("next: " + next); 31.89 + Matcher m1 = anonLine.matcher(next); 31.90 + m1.matches(); 31.91 + if (!m1.group(1).equals("1")) { 31.92 + throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1)); 31.93 + } 31.94 + checkPositiveInt(m1.group(2)); 31.95 + checkPositiveInt(m1.group(3)); 31.96 + } 31.97 + } 31.98 + } 31.99 + } 31.100 + 31.101 + private static void checkPositiveInt(String s) throws Exception { 31.102 + if (Integer.parseInt(s) <= 0) { 31.103 + throw new Exception("Value should have been > 0: " + s); 31.104 + } 31.105 + } 31.106 + 31.107 + public static class DummyClassLoader extends ClassLoader { 31.108 + 31.109 + public static final String CLASS_NAME = "TestClass"; 31.110 + 31.111 + static ByteBuffer readClassFile(String name) 31.112 + { 31.113 + File f = new File(System.getProperty("test.classes", "."), 31.114 + name); 31.115 + try (FileInputStream fin = new FileInputStream(f); 31.116 + FileChannel fc = fin.getChannel()) 31.117 + { 31.118 + return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 31.119 + } catch (IOException e) { 31.120 + throw new RuntimeException("Can't open file: " + name, e); 31.121 + } 31.122 + } 31.123 + 31.124 + protected Class<?> loadClass(String name, boolean resolve) 31.125 + throws ClassNotFoundException 31.126 + { 31.127 + Class<?> c; 31.128 + if (!"TestClass".equals(name)) { 31.129 + c = super.loadClass(name, resolve); 31.130 + } else { 31.131 + // should not delegate to the system class loader 31.132 + c = findClass(name); 31.133 + if (resolve) { 31.134 + resolveClass(c); 31.135 + } 31.136 + } 31.137 + return c; 31.138 + } 31.139 + 31.140 + protected Class<?> findClass(String name) 31.141 + throws ClassNotFoundException 31.142 + { 31.143 + if (!"TestClass".equals(name)) { 31.144 + throw new ClassNotFoundException("Unexpected class: " + name); 31.145 + } 31.146 + return defineClass(name, readClassFile(name + ".class"), null); 31.147 + } 31.148 + } /* DummyClassLoader */ 31.149 + 31.150 +} 31.151 + 31.152 +class TestClass { 31.153 + static { 31.154 + // force creation of anonymous class (for the lambdaform) 31.155 + Runnable r = () -> System.out.println("Hello"); 31.156 + r.run(); 31.157 + } 31.158 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/serviceability/dcmd/DcmdUtil.java Fri Jan 26 09:59:10 2018 -0800 32.3 @@ -0,0 +1,73 @@ 32.4 +/* 32.5 + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.23 + * or visit www.oracle.com if you need additional information or have any 32.24 + * questions. 32.25 + */ 32.26 + 32.27 +import sun.management.ManagementFactoryHelper; 32.28 + 32.29 +import com.sun.management.DiagnosticCommandMBean; 32.30 + 32.31 +public class DcmdUtil 32.32 +{ 32.33 + public static String executeDcmd(String cmd, String ... args) { 32.34 + DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean(); 32.35 + Object[] dcmdArgs = {args}; 32.36 + String[] signature = {String[].class.getName()}; 32.37 + 32.38 + try { 32.39 + System.out.print("> " + cmd + " "); 32.40 + for (String s : args) { 32.41 + System.out.print(s + " "); 32.42 + } 32.43 + System.out.println(":"); 32.44 + String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature); 32.45 + System.out.println(result); 32.46 + return result; 32.47 + } catch(Exception ex) { 32.48 + ex.printStackTrace(); 32.49 + } 32.50 + return null; 32.51 + } 32.52 + 32.53 + private static String transform(String name) { 32.54 + StringBuilder sb = new StringBuilder(); 32.55 + boolean toLower = true; 32.56 + boolean toUpper = false; 32.57 + for (int i = 0; i < name.length(); i++) { 32.58 + char c = name.charAt(i); 32.59 + if (c == '.' || c == '_') { 32.60 + toLower = false; 32.61 + toUpper = true; 32.62 + } else { 32.63 + if (toUpper) { 32.64 + toUpper = false; 32.65 + sb.append(Character.toUpperCase(c)); 32.66 + } else if(toLower) { 32.67 + sb.append(Character.toLowerCase(c)); 32.68 + } else { 32.69 + sb.append(c); 32.70 + } 32.71 + } 32.72 + } 32.73 + return sb.toString(); 32.74 + } 32.75 + 32.76 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/serviceability/dcmd/DynLibDcmdTest.java Fri Jan 26 09:59:10 2018 -0800 33.3 @@ -0,0 +1,67 @@ 33.4 +/* 33.5 + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + */ 33.26 + 33.27 +import java.util.HashSet; 33.28 +import java.util.Set; 33.29 +import com.oracle.java.testlibrary.Platform; 33.30 + 33.31 +/* 33.32 + * @test 33.33 + * @summary Test of VM.dynlib diagnostic command via MBean 33.34 + * @library /testlibrary 33.35 + * @compile DcmdUtil.java 33.36 + * @run main DynLibDcmdTest 33.37 + */ 33.38 + 33.39 +public class DynLibDcmdTest { 33.40 + 33.41 + public static void main(String[] args) throws Exception { 33.42 + String result = DcmdUtil.executeDcmd("VM.dynlibs"); 33.43 + 33.44 + String osDependentBaseString = null; 33.45 + if (Platform.isSolaris()) { 33.46 + osDependentBaseString = "lib%s.so"; 33.47 + } else if (Platform.isWindows()) { 33.48 + osDependentBaseString = "%s.dll"; 33.49 + } else if (Platform.isOSX()) { 33.50 + osDependentBaseString = "lib%s.dylib"; 33.51 + } else if (Platform.isLinux()) { 33.52 + osDependentBaseString = "lib%s.so"; 33.53 + } 33.54 + 33.55 + if (osDependentBaseString == null) { 33.56 + throw new Exception("Unsupported OS"); 33.57 + } 33.58 + 33.59 + Set<String> expectedContent = new HashSet<>(); 33.60 + expectedContent.add(String.format(osDependentBaseString, "jvm")); 33.61 + expectedContent.add(String.format(osDependentBaseString, "java")); 33.62 + expectedContent.add(String.format(osDependentBaseString, "management")); 33.63 + 33.64 + for(String expected : expectedContent) { 33.65 + if (!result.contains(expected)) { 33.66 + throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'"); 33.67 + } 33.68 + } 33.69 + } 33.70 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/serviceability/dcmd/gc/FinalizerInfoTest.java Fri Jan 26 09:59:10 2018 -0800 34.3 @@ -0,0 +1,87 @@ 34.4 +/* 34.5 + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.7 + * 34.8 + * This code is free software; you can redistribute it and/or modify it 34.9 + * under the terms of the GNU General Public License version 2 only, as 34.10 + * published by the Free Software Foundation. 34.11 + * 34.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 34.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 34.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 34.15 + * version 2 for more details (a copy is included in the LICENSE file that 34.16 + * accompanied this code). 34.17 + * 34.18 + * You should have received a copy of the GNU General Public License version 34.19 + * 2 along with this work; if not, write to the Free Software Foundation, 34.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 34.21 + * 34.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 34.23 + * or visit www.oracle.com if you need additional information or have any 34.24 + * questions. 34.25 + */ 34.26 + 34.27 +import com.oracle.java.testlibrary.JDKToolFinder; 34.28 +import com.oracle.java.testlibrary.OutputAnalyzer; 34.29 +import com.oracle.java.testlibrary.ProcessTools; 34.30 + 34.31 +import java.util.concurrent.TimeUnit; 34.32 +import java.util.concurrent.locks.Condition; 34.33 +import java.util.concurrent.locks.ReentrantLock; 34.34 + 34.35 +/* 34.36 + * @test 34.37 + * @summary 34.38 + * @library /testlibrary 34.39 + * @run main FinalizerInfoTest 34.40 + */ 34.41 +public class FinalizerInfoTest { 34.42 + static ReentrantLock lock = new ReentrantLock(); 34.43 + static volatile int wasInitialized = 0; 34.44 + static volatile int wasTrapped = 0; 34.45 + static final String cmd = "GC.finalizer_info"; 34.46 + static final int objectsCount = 1000; 34.47 + 34.48 + class MyObject { 34.49 + public MyObject() { 34.50 + // Make sure object allocation/deallocation is not optimized out 34.51 + wasInitialized += 1; 34.52 + } 34.53 + 34.54 + protected void finalize() { 34.55 + // Trap the object in a finalization queue 34.56 + wasTrapped += 1; 34.57 + lock.lock(); 34.58 + } 34.59 + } 34.60 + 34.61 + void run() throws Exception { 34.62 + try { 34.63 + lock.lock(); 34.64 + for(int i = 0; i < objectsCount; ++i) { 34.65 + new MyObject(); 34.66 + } 34.67 + System.out.println("Objects initialized: " + objectsCount); 34.68 + System.gc(); 34.69 + 34.70 + while(wasTrapped < 1) { 34.71 + // Waiting for gc thread. 34.72 + } 34.73 + 34.74 + 34.75 + String pid = Integer.toString(ProcessTools.getProcessId()); 34.76 + ProcessBuilder pb = new ProcessBuilder(); 34.77 + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, cmd}); 34.78 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 34.79 + output.shouldContain("MyObject"); 34.80 + } finally { 34.81 + lock.unlock(); 34.82 + } 34.83 + } 34.84 + 34.85 + public static void main(String[] args) throws Exception { 34.86 + new FinalizerInfoTest().run(); 34.87 + } 34.88 + 34.89 + 34.90 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/test/serviceability/dcmd/gc/HeapInfoTest.java Fri Jan 26 09:59:10 2018 -0800 35.3 @@ -0,0 +1,44 @@ 35.4 +/* 35.5 + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.7 + * 35.8 + * This code is free software; you can redistribute it and/or modify it 35.9 + * under the terms of the GNU General Public License version 2 only, as 35.10 + * published by the Free Software Foundation. 35.11 + * 35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 35.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 35.15 + * version 2 for more details (a copy is included in the LICENSE file that 35.16 + * accompanied this code). 35.17 + * 35.18 + * You should have received a copy of the GNU General Public License version 35.19 + * 2 along with this work; if not, write to the Free Software Foundation, 35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 35.21 + * 35.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 35.23 + * or visit www.oracle.com if you need additional information or have any 35.24 + * questions. 35.25 + */ 35.26 + 35.27 +import com.oracle.java.testlibrary.JDKToolFinder; 35.28 +import com.oracle.java.testlibrary.OutputAnalyzer; 35.29 +import com.oracle.java.testlibrary.ProcessTools; 35.30 + 35.31 +/* 35.32 + * @test 35.33 + * @summary Test of diagnostic command GC.heap_info 35.34 + * @library /testlibrary 35.35 + * @run main HeapInfoTest 35.36 + */ 35.37 +public class HeapInfoTest { 35.38 + 35.39 + public static void main(String[] args) throws Exception { 35.40 + String pid = Integer.toString(ProcessTools.getProcessId()); 35.41 + ProcessBuilder pb = new ProcessBuilder(); 35.42 + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "GC.heap_info"}); 35.43 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 35.44 + output.shouldContain("Metaspace"); 35.45 + } 35.46 +} 35.47 +