1 /*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2018 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 *
30 #include "utilities/debug.hpp"
31 #include "utilities/globalDefinitions.hpp"
32 #include "utilities/ostream.hpp"
33
34 class CodeHeapState : public CHeapObj<mtCode> {
35
36 public:
37 enum compType {
38 noComp = 0, // must be! due to initialization by memset to zero
39 c1,
40 c2,
41 jvmci,
42 lastComp
43 };
44
45 enum blobType {
46 noType = 0, // must be! due to initialization by memset to zero
47 // The nMethod_* values correspond to the CompiledMethod enum values.
48 // We can't use the CompiledMethod values 1:1 because we depend on noType == 0.
49 nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
50 nMethod_inuse, // executable. This is the "normal" state for a nmethod.
51 nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
52 nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
53 // Will transition to "zombie" after all activations are gone.
54 nMethod_zombie, // No more activations exist, ready for purge (remove from code cache).
55 nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie".
56 nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged.
57 nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations.
58 runtimeStub = nMethod_unloaded + 1,
59 ricochetStub,
60 deoptimizationStub,
61 uncommonTrapStub,
62 exceptionStub,
63 safepointStub,
64 adapterBlob,
65 mh_adapterBlob,
66 bufferBlob,
67 lastType
68 };
69
78 static void discard_SizeDistArray(outputStream* out);
79
80 static void update_SizeDistArray(outputStream* out, unsigned int len);
81
82 static const char* get_heapName(CodeHeap* heap);
83 static unsigned int findHeapIndex(outputStream* out, const char* heapName);
84 static void get_HeapStatGlobals(outputStream* out, const char* heapName);
85 static void set_HeapStatGlobals(outputStream* out, const char* heapName);
86
87 static void printBox(outputStream* out, const char border, const char* text1, const char* text2);
88 static void print_blobType_legend(outputStream* out);
89 static void print_space_legend(outputStream* out);
90 static void print_age_legend(outputStream* out);
91 static void print_blobType_single(outputStream *ast, u2 /* blobType */ type);
92 static void print_count_single(outputStream *ast, unsigned short count);
93 static void print_space_single(outputStream *ast, unsigned short space);
94 static void print_age_single(outputStream *ast, unsigned int age);
95 static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
96 static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
97 static blobType get_cbType(CodeBlob* cb);
98
99 public:
100 static void discard(outputStream* out, CodeHeap* heap);
101 static void aggregate(outputStream* out, CodeHeap* heap, size_t granularity);
102 static void print_usedSpace(outputStream* out, CodeHeap* heap);
103 static void print_freeSpace(outputStream* out, CodeHeap* heap);
104 static void print_count(outputStream* out, CodeHeap* heap);
105 static void print_space(outputStream* out, CodeHeap* heap);
106 static void print_age(outputStream* out, CodeHeap* heap);
107 static void print_names(outputStream* out, CodeHeap* heap);
108 };
109
110 //----------------
111 // StatElement
112 //----------------
113 // Each analysis granule is represented by an instance of
114 // this StatElement struct. It collects and aggregates all
115 // information describing the allocated contents of the granule.
116 // Free (unallocated) contents is not considered (see FreeBlk for that).
117 // All StatElements of a heap segment are stored in the related StatArray.
147 // All FreeBlks of a heap segment are stored in the related FreeArray.
148 struct FreeBlk : public CHeapObj<mtCode> {
149 HeapBlock* start; // address of free block
150 unsigned int len; // length of free block
151
152 unsigned int gap; // gap to next free block
153 unsigned int index; // sequential number of free block
154 unsigned short n_gapBlocks; // # used blocks in gap
155 bool stubs_in_gap; // The occupied space between this and the next free block contains (unmovable) stubs or blobs.
156 };
157
158 //--------------
159 // TopSizeBlk
160 //--------------
161 // The n largest blocks in the code heap are represented in an instance
162 // of this TopSizeBlk struct. It collects all information we need to
163 // know about those largest blocks.
164 // All TopSizeBlks of a heap segment are stored in the related TopSizeArray.
165 struct TopSizeBlk : public CHeapObj<mtCode> {
166 HeapBlock* start; // address of block
167 unsigned int len; // length of block, in _segment_size units. Will never overflow int.
168
169 unsigned int index; // ordering index, 0 is largest block
170 // contains array index of next smaller block
171 // -1 indicates end of list
172 CompLevel level; // optimization level (see globalDefinitions.hpp)
173 u2 compiler; // compiler which generated this blob
174 u2 type; // blob type
175 };
176
177 //---------------------------
178 // SizeDistributionElement
179 //---------------------------
180 // During CodeHeap analysis, each allocated code block is associated with a
181 // SizeDistributionElement according to its size. Later on, the array of
182 // SizeDistributionElements is used to print a size distribution bar graph.
183 // All SizeDistributionElements of a heap segment are stored in the related SizeDistributionArray.
184 struct SizeDistributionElement : public CHeapObj<mtCode> {
185 // Range is [rangeStart..rangeEnd).
186 unsigned int rangeStart; // start of length range, in _segment_size units.
187 unsigned int rangeEnd; // end of length range, in _segment_size units.
188 unsigned int lenSum; // length of block, in _segment_size units. Will never overflow int.
189
190 unsigned int count; // number of blocks assigned to this range.
191 };
198 // Thats what the CodeHeapStat and CodeHeapStatArray are used for.
199 // Before a heap segment is processed, the contents of the CodeHeapStat
200 // element is copied to the global variables (get_HeapStatGlobals).
201 // When processing is done, the possibly modified global variables are
202 // copied back (set_HeapStatGlobals) to the CodeHeapStat element.
203 struct CodeHeapStat {
204 StatElement* StatArray;
205 struct FreeBlk* FreeArray;
206 struct TopSizeBlk* TopSizeArray;
207 struct SizeDistributionElement* SizeDistributionArray;
208 const char* heapName;
209 size_t segment_size;
210 // StatElement data
211 size_t alloc_granules;
212 size_t granule_size;
213 bool segment_granules;
214 unsigned int nBlocks_t1;
215 unsigned int nBlocks_t2;
216 unsigned int nBlocks_alive;
217 unsigned int nBlocks_dead;
218 unsigned int nBlocks_inconstr;
219 unsigned int nBlocks_unloaded;
220 unsigned int nBlocks_stub;
221 // FreeBlk data
222 unsigned int alloc_freeBlocks;
223 // UsedBlk data
224 unsigned int alloc_topSizeBlocks;
225 unsigned int used_topSizeBlocks;
226 // method hotness data. Temperature range is [-reset_val..+reset_val]
227 int avgTemp;
228 int maxTemp;
229 int minTemp;
230 };
231
232 #endif // SHARE_CODE_CODEHEAPSTATE_HPP
|
1 /*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2018, 2019 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 *
30 #include "utilities/debug.hpp"
31 #include "utilities/globalDefinitions.hpp"
32 #include "utilities/ostream.hpp"
33
34 class CodeHeapState : public CHeapObj<mtCode> {
35
36 public:
37 enum compType {
38 noComp = 0, // must be! due to initialization by memset to zero
39 c1,
40 c2,
41 jvmci,
42 lastComp
43 };
44
45 enum blobType {
46 noType = 0, // must be! due to initialization by memset to zero
47 // The nMethod_* values correspond to the CompiledMethod enum values.
48 // We can't use the CompiledMethod values 1:1 because we depend on noType == 0.
49 nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
50 // can't be observed while holding Compile_lock and CodeCache_lock simultaneously.
51 // left in here for completeness (and to document we spent a thought).
52 nMethod_inuse, // executable. This is the "normal" state for a nmethod.
53 nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
54 nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
55 // Will transition to "zombie" after all activations are gone.
56 nMethod_zombie, // No more activations exist, ready for purge (remove from code cache).
57 nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie".
58 nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged.
59 nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations.
60 runtimeStub = nMethod_unloaded + 1,
61 ricochetStub,
62 deoptimizationStub,
63 uncommonTrapStub,
64 exceptionStub,
65 safepointStub,
66 adapterBlob,
67 mh_adapterBlob,
68 bufferBlob,
69 lastType
70 };
71
80 static void discard_SizeDistArray(outputStream* out);
81
82 static void update_SizeDistArray(outputStream* out, unsigned int len);
83
84 static const char* get_heapName(CodeHeap* heap);
85 static unsigned int findHeapIndex(outputStream* out, const char* heapName);
86 static void get_HeapStatGlobals(outputStream* out, const char* heapName);
87 static void set_HeapStatGlobals(outputStream* out, const char* heapName);
88
89 static void printBox(outputStream* out, const char border, const char* text1, const char* text2);
90 static void print_blobType_legend(outputStream* out);
91 static void print_space_legend(outputStream* out);
92 static void print_age_legend(outputStream* out);
93 static void print_blobType_single(outputStream *ast, u2 /* blobType */ type);
94 static void print_count_single(outputStream *ast, unsigned short count);
95 static void print_space_single(outputStream *ast, unsigned short space);
96 static void print_age_single(outputStream *ast, unsigned int age);
97 static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
98 static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
99 static blobType get_cbType(CodeBlob* cb);
100 static bool blob_access_is_safe(CodeBlob* this_blob);
101 static bool nmethod_access_is_safe(nmethod* nm);
102 static bool holding_required_locks();
103
104 public:
105 static void discard(outputStream* out, CodeHeap* heap);
106 static void aggregate(outputStream* out, CodeHeap* heap, size_t granularity);
107 static void print_usedSpace(outputStream* out, CodeHeap* heap);
108 static void print_freeSpace(outputStream* out, CodeHeap* heap);
109 static void print_count(outputStream* out, CodeHeap* heap);
110 static void print_space(outputStream* out, CodeHeap* heap);
111 static void print_age(outputStream* out, CodeHeap* heap);
112 static void print_names(outputStream* out, CodeHeap* heap);
113 };
114
115 //----------------
116 // StatElement
117 //----------------
118 // Each analysis granule is represented by an instance of
119 // this StatElement struct. It collects and aggregates all
120 // information describing the allocated contents of the granule.
121 // Free (unallocated) contents is not considered (see FreeBlk for that).
122 // All StatElements of a heap segment are stored in the related StatArray.
152 // All FreeBlks of a heap segment are stored in the related FreeArray.
153 struct FreeBlk : public CHeapObj<mtCode> {
154 HeapBlock* start; // address of free block
155 unsigned int len; // length of free block
156
157 unsigned int gap; // gap to next free block
158 unsigned int index; // sequential number of free block
159 unsigned short n_gapBlocks; // # used blocks in gap
160 bool stubs_in_gap; // The occupied space between this and the next free block contains (unmovable) stubs or blobs.
161 };
162
163 //--------------
164 // TopSizeBlk
165 //--------------
166 // The n largest blocks in the code heap are represented in an instance
167 // of this TopSizeBlk struct. It collects all information we need to
168 // know about those largest blocks.
169 // All TopSizeBlks of a heap segment are stored in the related TopSizeArray.
170 struct TopSizeBlk : public CHeapObj<mtCode> {
171 HeapBlock* start; // address of block
172 const char* blob_name; // name of blob (mostly: name_and_sig of nmethod)
173 unsigned int len; // length of block, in _segment_size units. Will never overflow int.
174
175 unsigned int index; // ordering index, 0 is largest block
176 // contains array index of next smaller block
177 // -1 indicates end of list
178
179 unsigned int nm_size; // nmeethod total size (if nmethod, 0 otherwise)
180 int temperature; // nmethod temperature (if nmethod, 0 otherwise)
181 CompLevel level; // optimization level (see globalDefinitions.hpp)
182 u2 compiler; // compiler which generated this blob
183 u2 type; // blob type
184 };
185
186 //---------------------------
187 // SizeDistributionElement
188 //---------------------------
189 // During CodeHeap analysis, each allocated code block is associated with a
190 // SizeDistributionElement according to its size. Later on, the array of
191 // SizeDistributionElements is used to print a size distribution bar graph.
192 // All SizeDistributionElements of a heap segment are stored in the related SizeDistributionArray.
193 struct SizeDistributionElement : public CHeapObj<mtCode> {
194 // Range is [rangeStart..rangeEnd).
195 unsigned int rangeStart; // start of length range, in _segment_size units.
196 unsigned int rangeEnd; // end of length range, in _segment_size units.
197 unsigned int lenSum; // length of block, in _segment_size units. Will never overflow int.
198
199 unsigned int count; // number of blocks assigned to this range.
200 };
207 // Thats what the CodeHeapStat and CodeHeapStatArray are used for.
208 // Before a heap segment is processed, the contents of the CodeHeapStat
209 // element is copied to the global variables (get_HeapStatGlobals).
210 // When processing is done, the possibly modified global variables are
211 // copied back (set_HeapStatGlobals) to the CodeHeapStat element.
212 struct CodeHeapStat {
213 StatElement* StatArray;
214 struct FreeBlk* FreeArray;
215 struct TopSizeBlk* TopSizeArray;
216 struct SizeDistributionElement* SizeDistributionArray;
217 const char* heapName;
218 size_t segment_size;
219 // StatElement data
220 size_t alloc_granules;
221 size_t granule_size;
222 bool segment_granules;
223 unsigned int nBlocks_t1;
224 unsigned int nBlocks_t2;
225 unsigned int nBlocks_alive;
226 unsigned int nBlocks_dead;
227 unsigned int nBlocks_unloaded;
228 unsigned int nBlocks_stub;
229 // FreeBlk data
230 unsigned int alloc_freeBlocks;
231 // UsedBlk data
232 unsigned int alloc_topSizeBlocks;
233 unsigned int used_topSizeBlocks;
234 // method hotness data. Temperature range is [-reset_val..+reset_val]
235 int avgTemp;
236 int maxTemp;
237 int minTemp;
238 };
239
240 #endif // SHARE_CODE_CODEHEAPSTATE_HPP
|