1 /*
  2  * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2018, 2020 SAP SE. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "precompiled.hpp"
 27 #include "memory/metaspace/freeBlocks.hpp"
 28 #include "memory/metaspace/metaspaceAlignment.hpp"
 29 #include "memory/metaspace/metaspaceCommon.hpp"
 30 #include "memory/metaspace/metaspaceSettings.hpp"
 31 #include "memory/metaspace/virtualSpaceNode.hpp"
 32 #include "utilities/align.hpp"
 33 #include "utilities/debug.hpp"
 34 #include "utilities/globalDefinitions.hpp"
 35 #include "utilities/ostream.hpp"
 36 
 37 namespace metaspace {
 38 
 39 // Print a size, in words, scaled.
 40 void print_scaled_words(outputStream* st, size_t word_size, size_t scale, int width) {
 41   print_human_readable_size(st, word_size * sizeof(MetaWord), scale, width);
 42 }
 43 
 44 // Convenience helper: prints a size value and a percentage.
 45 void print_scaled_words_and_percentage(outputStream* st, size_t word_size, size_t compare_word_size, size_t scale, int width) {
 46   print_scaled_words(st, word_size, scale, width);
 47   st->print(" (");
 48   print_percentage(st, compare_word_size, word_size);
 49   st->print(")");
 50 }
 51 
 52 static const char* display_unit_for_scale(size_t scale) {
 53   const char* s = NULL;
 54   switch(scale) {
 55     case 1: s = "bytes"; break;
 56     case BytesPerWord: s = "words"; break;
 57     case K: s = "KB"; break;
 58     case M: s = "MB"; break;
 59     case G: s = "GB"; break;
 60     default:
 61       ShouldNotReachHere();
 62   }
 63   return s;
 64 }
 65 
 66 // Print a human readable size.
 67 // byte_size: size, in bytes, to be printed.
 68 // scale: one of 1 (byte-wise printing), sizeof(word) (word-size printing), K, M, G (scaled by KB, MB, GB respectively,
 69 //         or 0, which means the best scale is chosen dynamically.
 70 // width: printing width.
 71 void print_human_readable_size(outputStream* st, size_t byte_size, size_t scale, int width)  {
 72   if (scale == 0) {
 73     // Dynamic mode. Choose scale for this value.
 74     if (byte_size == 0) {
 75       // Zero values are printed as bytes.
 76       scale = 1;
 77     } else {
 78       if (byte_size >= G) {
 79         scale = G;
 80       } else if (byte_size >= M) {
 81         scale = M;
 82       } else if (byte_size >= K) {
 83         scale = K;
 84       } else {
 85         scale = 1;
 86       }
 87     }
 88     return print_human_readable_size(st, byte_size, scale, width);
 89   }
 90 
 91 #ifdef ASSERT
 92   assert(scale == 1 || scale == BytesPerWord ||
 93          scale == K || scale == M || scale == G, "Invalid scale");
 94   // Special case: printing wordsize should only be done with word-sized values
 95   if (scale == BytesPerWord) {
 96     assert(byte_size % BytesPerWord == 0, "not word sized");
 97   }
 98 #endif
 99 
100   if (width == -1) {
101     if (scale == 1) {
102       st->print(SIZE_FORMAT " bytes", byte_size);
103     } else if (scale == BytesPerWord) {
104       st->print(SIZE_FORMAT " words", byte_size / BytesPerWord);
105     } else {
106       const char* display_unit = display_unit_for_scale(scale);
107       float display_value = (float) byte_size / scale;
108       // Prevent very small but non-null values showing up as 0.00.
109       if (byte_size > 0 && display_value < 0.01f) {
110         st->print("<0.01 %s", display_unit);
111       } else {
112         st->print("%.2f %s", display_value, display_unit);
113       }
114     }
115   } else {
116     if (scale == 1) {
117       st->print("%*" PRIuPTR " bytes", width, byte_size);
118     } else if (scale == BytesPerWord) {
119       st->print("%*" PRIuPTR " words", width, byte_size / BytesPerWord);
120     } else {
121       const char* display_unit = display_unit_for_scale(scale);
122       float display_value = (float) byte_size / scale;
123       // Since we use width to display a number with two trailing digits, increase it a bit.
124       width += 3;
125       // Prevent very small but non-null values showing up as 0.00.
126       if (byte_size > 0 && display_value < 0.01f) {
127         st->print("%*s %s", width, "<0.01", display_unit);
128       } else {
129         st->print("%*.2f %s", width, display_value, display_unit);
130       }
131     }
132   }
133 }
134 
135 // Prints a percentage value. Values smaller than 1% but not 0 are displayed as "<1%", values
136 // larger than 99% but not 100% are displayed as ">100%".
137 void print_percentage(outputStream* st, size_t total, size_t part) {
138   if (total == 0) {
139     st->print("  ?%%");
140   } else if (part == 0) {
141     st->print("  0%%");
142   } else if (part == total) {
143     st->print("100%%");
144   } else {
145     // Note: clearly print very-small-but-not-0% and very-large-but-not-100% percentages.
146     float p = ((float)part / total) * 100.0f;
147     if (p < 1.0f) {
148       st->print(" <1%%");
149     } else if (p > 99.0f){
150       st->print(">99%%");
151     } else {
152       st->print("%3.0f%%", p);
153     }
154   }
155 }
156 
157 const char* loaders_plural(uintx num) {
158   return num == 1 ? "loader" : "loaders";
159 }
160 
161 const char* classes_plural(uintx num) {
162   return num == 1 ? "class" : "classes";
163 }
164 
165 void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared) {
166   out->print(UINTX_FORMAT " %s", classes, classes_plural(classes));
167   if (classes_shared > 0) {
168     out->print(" (" UINTX_FORMAT " shared)", classes_shared);
169   }
170 }
171 


















172 } // namespace metaspace
173 
--- EOF ---