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 static bool blob_access_is_safe(CodeBlob* this_blob, CodeBlob* prev_blob);
99
100 public:
101 static void discard(outputStream* out, CodeHeap* heap);
102 static void aggregate(outputStream* out, CodeHeap* heap, size_t granularity);
103 static void print_usedSpace(outputStream* out, CodeHeap* heap);
104 static void print_freeSpace(outputStream* out, CodeHeap* heap);
105 static void print_count(outputStream* out, CodeHeap* heap);
106 static void print_space(outputStream* out, CodeHeap* heap);
107 static void print_age(outputStream* out, CodeHeap* heap);
108 static void print_names(outputStream* out, CodeHeap* heap);
109 };
110
111 //----------------
112 // StatElement
113 //----------------
114 // Each analysis granule is represented by an instance of
115 // this StatElement struct. It collects and aggregates all
116 // information describing the allocated contents of the granule.
117 // Free (unallocated) contents is not considered (see FreeBlk for that).
118 // All StatElements of a heap segment are stored in the related StatArray.
148 // All FreeBlks of a heap segment are stored in the related FreeArray.
149 struct FreeBlk : public CHeapObj<mtCode> {
150 HeapBlock* start; // address of free block
151 unsigned int len; // length of free block
152
153 unsigned int gap; // gap to next free block
154 unsigned int index; // sequential number of free block
155 unsigned short n_gapBlocks; // # used blocks in gap
156 bool stubs_in_gap; // The occupied space between this and the next free block contains (unmovable) stubs or blobs.
157 };
158
159 //--------------
160 // TopSizeBlk
161 //--------------
162 // The n largest blocks in the code heap are represented in an instance
163 // of this TopSizeBlk struct. It collects all information we need to
164 // know about those largest blocks.
165 // All TopSizeBlks of a heap segment are stored in the related TopSizeArray.
166 struct TopSizeBlk : public CHeapObj<mtCode> {
167 HeapBlock* start; // address of block
168 unsigned int len; // length of block, in _segment_size units. Will never overflow int.
169
170 unsigned int index; // ordering index, 0 is largest block
171 // contains array index of next smaller block
172 // -1 indicates end of list
173 CompLevel level; // optimization level (see globalDefinitions.hpp)
174 u2 compiler; // compiler which generated this blob
175 u2 type; // blob type
176 };
177
178 //---------------------------
179 // SizeDistributionElement
180 //---------------------------
181 // During CodeHeap analysis, each allocated code block is associated with a
182 // SizeDistributionElement according to its size. Later on, the array of
183 // SizeDistributionElements is used to print a size distribution bar graph.
184 // All SizeDistributionElements of a heap segment are stored in the related SizeDistributionArray.
185 struct SizeDistributionElement : public CHeapObj<mtCode> {
186 // Range is [rangeStart..rangeEnd).
187 unsigned int rangeStart; // start of length range, in _segment_size units.
188 unsigned int rangeEnd; // end of length range, in _segment_size units.
189 unsigned int lenSum; // length of block, in _segment_size units. Will never overflow int.
190
191 unsigned int count; // number of blocks assigned to this range.
192 };
199 // Thats what the CodeHeapStat and CodeHeapStatArray are used for.
200 // Before a heap segment is processed, the contents of the CodeHeapStat
201 // element is copied to the global variables (get_HeapStatGlobals).
202 // When processing is done, the possibly modified global variables are
203 // copied back (set_HeapStatGlobals) to the CodeHeapStat element.
204 struct CodeHeapStat {
205 StatElement* StatArray;
206 struct FreeBlk* FreeArray;
207 struct TopSizeBlk* TopSizeArray;
208 struct SizeDistributionElement* SizeDistributionArray;
209 const char* heapName;
210 size_t segment_size;
211 // StatElement data
212 size_t alloc_granules;
213 size_t granule_size;
214 bool segment_granules;
215 unsigned int nBlocks_t1;
216 unsigned int nBlocks_t2;
217 unsigned int nBlocks_alive;
218 unsigned int nBlocks_dead;
219 unsigned int nBlocks_inconstr;
220 unsigned int nBlocks_unloaded;
221 unsigned int nBlocks_stub;
222 // FreeBlk data
223 unsigned int alloc_freeBlocks;
224 // UsedBlk data
225 unsigned int alloc_topSizeBlocks;
226 unsigned int used_topSizeBlocks;
227 // method hotness data. Temperature range is [-reset_val..+reset_val]
228 int avgTemp;
229 int maxTemp;
230 int minTemp;
231 };
232
233 #endif // SHARE_CODE_CODEHEAPSTATE_HPP
|
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
|