31 |
32 |
32 class outputStream; |
33 class outputStream; |
33 |
34 |
34 namespace metaspace { |
35 namespace metaspace { |
35 |
36 |
36 enum ChunkSizes { // in words. |
|
37 ClassSpecializedChunk = 128, |
|
38 SpecializedChunk = 128, |
|
39 ClassSmallChunk = 256, |
|
40 SmallChunk = 512, |
|
41 ClassMediumChunk = 4 * K, |
|
42 MediumChunk = 8 * K |
|
43 }; |
|
44 |
37 |
45 // Print a size, in words, scaled. |
38 // Print a size, in words, scaled. |
46 void print_scaled_words(outputStream* st, size_t word_size, size_t scale = 0, int width = -1); |
39 void print_scaled_words(outputStream* st, size_t word_size, size_t scale = 0, int width = -1); |
47 |
40 |
48 // Convenience helper: prints a size value and a percentage. |
41 // Convenience helper: prints a size value and a percentage. |
63 #define assert_is_aligned(value, alignment) \ |
56 #define assert_is_aligned(value, alignment) \ |
64 assert(is_aligned((value), (alignment)), \ |
57 assert(is_aligned((value), (alignment)), \ |
65 SIZE_FORMAT_HEX " is not aligned to " \ |
58 SIZE_FORMAT_HEX " is not aligned to " \ |
66 SIZE_FORMAT, (size_t)(uintptr_t)value, (alignment)) |
59 SIZE_FORMAT, (size_t)(uintptr_t)value, (alignment)) |
67 |
60 |
68 // Internal statistics. |
|
69 #ifdef ASSERT |
|
70 struct internal_statistics_t { |
|
71 // Number of allocations. |
|
72 uintx num_allocs; |
|
73 // Number of times a ClassLoaderMetaspace was born... |
|
74 uintx num_metaspace_births; |
|
75 // ... and died. |
|
76 uintx num_metaspace_deaths; |
|
77 // Number of times VirtualSpaceListNodes were created... |
|
78 uintx num_vsnodes_created; |
|
79 // ... and purged. |
|
80 uintx num_vsnodes_purged; |
|
81 // Number of times we expanded the committed section of the space. |
|
82 uintx num_committed_space_expanded; |
|
83 // Number of deallocations |
|
84 uintx num_deallocs; |
|
85 // Number of deallocations triggered from outside ("real" deallocations). |
|
86 uintx num_external_deallocs; |
|
87 // Number of times an allocation was satisfied from deallocated blocks. |
|
88 uintx num_allocs_from_deallocated_blocks; |
|
89 // Number of times a chunk was added to the freelist |
|
90 uintx num_chunks_added_to_freelist; |
|
91 // Number of times a chunk was removed from the freelist |
|
92 uintx num_chunks_removed_from_freelist; |
|
93 // Number of chunk merges |
|
94 uintx num_chunk_merges; |
|
95 // Number of chunk splits |
|
96 uintx num_chunk_splits; |
|
97 }; |
|
98 extern internal_statistics_t g_internal_statistics; |
|
99 #endif |
|
100 |
|
101 // ChunkIndex defines the type of chunk. |
|
102 // Chunk types differ by size: specialized < small < medium, chunks |
|
103 // larger than medium are humongous chunks of varying size. |
|
104 enum ChunkIndex { |
|
105 ZeroIndex = 0, |
|
106 SpecializedIndex = ZeroIndex, |
|
107 SmallIndex = SpecializedIndex + 1, |
|
108 MediumIndex = SmallIndex + 1, |
|
109 HumongousIndex = MediumIndex + 1, |
|
110 NumberOfFreeLists = 3, |
|
111 NumberOfInUseLists = 4 |
|
112 }; |
|
113 |
|
114 // Utility functions. |
|
115 size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class); |
|
116 ChunkIndex get_chunk_type_by_size(size_t size, bool is_class); |
|
117 |
|
118 ChunkIndex next_chunk_index(ChunkIndex i); |
|
119 ChunkIndex prev_chunk_index(ChunkIndex i); |
|
120 // Returns a descriptive name for a chunk type. |
|
121 const char* chunk_size_name(ChunkIndex index); |
|
122 |
|
123 // Verify chunk sizes. |
|
124 inline bool is_valid_chunksize(bool is_class, size_t size) { |
|
125 const size_t reasonable_maximum_humongous_chunk_size = 1 * G; |
|
126 return is_aligned(size, sizeof(MetaWord)) && |
|
127 size < reasonable_maximum_humongous_chunk_size && |
|
128 is_class ? |
|
129 (size == ClassSpecializedChunk || size == ClassSmallChunk || size >= ClassMediumChunk) : |
|
130 (size == SpecializedChunk || size == SmallChunk || size >= MediumChunk); |
|
131 } |
|
132 |
|
133 // Verify chunk type. |
|
134 inline bool is_valid_chunktype(ChunkIndex index) { |
|
135 return index == SpecializedIndex || index == SmallIndex || |
|
136 index == MediumIndex || index == HumongousIndex; |
|
137 } |
|
138 |
|
139 inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) { |
|
140 return is_valid_chunktype(index) && index != HumongousIndex; |
|
141 } |
|
142 |
61 |
143 // Pretty printing helpers |
62 // Pretty printing helpers |
144 const char* classes_plural(uintx num); |
63 const char* classes_plural(uintx num); |
145 const char* loaders_plural(uintx num); |
64 const char* loaders_plural(uintx num); |
146 void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared); |
65 void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared); |