- Notifications
You must be signed in to change notification settings - Fork 5.8k
/
Copy pathcodeHeapState.hpp
236 lines (216 loc) · 11 KB
/
codeHeapState.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_CODE_CODEHEAPSTATE_HPP
#defineSHARE_CODE_CODEHEAPSTATE_HPP
#include"memory/heap.hpp"
#include"utilities/debug.hpp"
#include"utilities/globalDefinitions.hpp"
#include"utilities/ostream.hpp"
classCodeHeapState : publicCHeapObj<mtCode> {
public:
enum compType {
noComp = 0, // must be! due to initialization by memset to zero
c1,
c2,
jvmci,
lastComp
};
enum blobType {
noType = 0, // must be! due to initialization by memset to zero
// The nMethod_* values correspond to the nmethod enum values.
// We can't use the nmethod values 1:1 because we depend on noType == 0.
nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
// can't be observed while holding Compile_lock and CodeCache_lock simultaneously.
// left in here for completeness (and to document we spent a thought).
nMethod_inuse, // executable. This is the "normal" state for a nmethod.
nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
runtimeStub,
ricochetStub,
deoptimizationStub,
uncommonTrapStub,
exceptionStub,
safepointStub,
adapterBlob,
mh_adapterBlob,
bufferBlob,
lastType
};
private:
staticvoidprepare_StatArray(outputStream* out, size_t nElem, size_t granularity, constchar* heapName);
staticvoidprepare_FreeArray(outputStream* out, unsignedint nElem, constchar* heapName);
staticvoidprepare_TopSizeArray(outputStream* out, unsignedint nElem, constchar* heapName);
staticvoidprepare_SizeDistArray(outputStream* out, unsignedint nElem, constchar* heapName);
staticvoiddiscard_StatArray(outputStream* out);
staticvoiddiscard_FreeArray(outputStream* out);
staticvoiddiscard_TopSizeArray(outputStream* out);
staticvoiddiscard_SizeDistArray(outputStream* out);
staticvoidupdate_SizeDistArray(outputStream* out, unsignedint len);
staticconstchar* get_heapName(CodeHeap* heap);
staticunsignedintfindHeapIndex(outputStream* out, constchar* heapName);
staticvoidget_HeapStatGlobals(outputStream* out, constchar* heapName);
staticvoidset_HeapStatGlobals(outputStream* out, constchar* heapName);
staticvoidprintBox(outputStream* out, constchar border, constchar* text1, constchar* text2);
staticvoidprint_blobType_legend(outputStream* out);
staticvoidprint_space_legend(outputStream* out);
staticvoidprint_age_legend(outputStream* out);
staticvoidprint_blobType_single(outputStream *ast, u2 /* blobType */ type);
staticvoidprint_count_single(outputStream *ast, unsignedshort count);
staticvoidprint_space_single(outputStream *ast, unsignedshort space);
staticvoidprint_age_single(outputStream *ast, int age);
staticvoidprint_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsignedint ix, unsignedint gpl);
staticvoidprint_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsignedint ix, unsignedint gpl);
staticvoidprint_aggregate_missing(outputStream* out, constchar* heapName);
static blobType get_cbType(CodeBlob* cb);
staticboolblob_access_is_safe(CodeBlob* this_blob);
staticboolnmethod_access_is_safe(nmethod* nm);
staticboolholding_required_locks();
public:
staticvoiddiscard(outputStream* out, CodeHeap* heap);
staticvoidaggregate(outputStream* out, CodeHeap* heap, size_t granularity);
staticvoidprint_usedSpace(outputStream* out, CodeHeap* heap);
staticvoidprint_freeSpace(outputStream* out, CodeHeap* heap);
staticvoidprint_count(outputStream* out, CodeHeap* heap);
staticvoidprint_space(outputStream* out, CodeHeap* heap);
staticvoidprint_age(outputStream* out, CodeHeap* heap);
staticvoidprint_names(outputStream* out, CodeHeap* heap);
};
//----------------
// StatElement
//----------------
// Each analysis granule is represented by an instance of
// this StatElement struct. It collects and aggregates all
// information describing the allocated contents of the granule.
// Free (unallocated) contents is not considered (see FreeBlk for that).
// All StatElements of a heap segment are stored in the related StatArray.
// Current size: 40 bytes + 8 bytes class header.
classStatElement : publicCHeapObj<mtCode> {
public:
// A note on ages: The compilation_id easily overflows unsigned short in large systems
int t1_age; // oldest compilation_id of tier1 nMethods.
int t2_age; // oldest compilation_id of tier2 nMethods.
int tx_age; // oldest compilation_id of inactive/not entrant nMethods.
unsignedshort t1_space; // in units of _segment_size to "prevent" overflow
unsignedshort t2_space; // in units of _segment_size to "prevent" overflow
unsignedshort tx_space; // in units of _segment_size to "prevent" overflow
unsignedshort dead_space; // in units of _segment_size to "prevent" overflow
unsignedshort stub_space; // in units of _segment_size to "prevent" overflow
unsignedshort t1_count;
unsignedshort t2_count;
unsignedshort tx_count;
unsignedshort dead_count;
unsignedshort stub_count;
CompLevel level; // optimization level (see globalDefinitions.hpp)
//---< replaced the correct enum typing with u2 to save space.
u2 compiler; // compiler which generated this blob. Type is CodeHeapState::compType
u2 type; // used only if granularity == segment_size. Type is CodeHeapState::blobType
};
//-----------
// FreeBlk
//-----------
// Each free block in the code heap is represented by an instance
// of this FreeBlk struct. It collects all information we need to
// know about each free block.
// All FreeBlks of a heap segment are stored in the related FreeArray.
structFreeBlk : publicCHeapObj<mtCode> {
HeapBlock* start; // address of free block
unsignedint len; // length of free block
unsignedint gap; // gap to next free block
unsignedint index; // sequential number of free block
unsignedshort n_gapBlocks; // # used blocks in gap
bool stubs_in_gap; // The occupied space between this and the next free block contains (unmovable) stubs or blobs.
};
//--------------
// TopSizeBlk
//--------------
// The n largest blocks in the code heap are represented in an instance
// of this TopSizeBlk struct. It collects all information we need to
// know about those largest blocks.
// All TopSizeBlks of a heap segment are stored in the related TopSizeArray.
structTopSizeBlk : publicCHeapObj<mtCode> {
HeapBlock* start; // address of block
constchar* blob_name; // name of blob (mostly: name_and_sig of nmethod)
unsignedint len; // length of block, in _segment_size units. Will never overflow int.
unsignedint index; // ordering index, 0 is largest block
// contains array index of next smaller block
// -1 indicates end of list
unsignedint nm_size; // nmeethod total size (if nmethod, 0 otherwise)
int temperature; // nmethod temperature (if nmethod, 0 otherwise)
CompLevel level; // optimization level (see globalDefinitions.hpp)
u2 compiler; // compiler which generated this blob
u2 type; // blob type
};
//---------------------------
// SizeDistributionElement
//---------------------------
// During CodeHeap analysis, each allocated code block is associated with a
// SizeDistributionElement according to its size. Later on, the array of
// SizeDistributionElements is used to print a size distribution bar graph.
// All SizeDistributionElements of a heap segment are stored in the related SizeDistributionArray.
structSizeDistributionElement : publicCHeapObj<mtCode> {
// Range is [rangeStart..rangeEnd).
unsignedint rangeStart; // start of length range, in _segment_size units.
unsignedint rangeEnd; // end of length range, in _segment_size units.
unsignedint lenSum; // length of block, in _segment_size units. Will never overflow int.
unsignedint count; // number of blocks assigned to this range.
};
//----------------
// CodeHeapStat
//----------------
// Because we have to deal with multiple CodeHeaps, we need to
// collect "global" information in a segment-specific way as well.
// That's what the CodeHeapStat and CodeHeapStatArray are used for.
// Before a heap segment is processed, the contents of the CodeHeapStat
// element is copied to the global variables (get_HeapStatGlobals).
// When processing is done, the possibly modified global variables are
// copied back (set_HeapStatGlobals) to the CodeHeapStat element.
structCodeHeapStat {
StatElement* StatArray;
structFreeBlk* FreeArray;
structTopSizeBlk* TopSizeArray;
structSizeDistributionElement* SizeDistributionArray;
constchar* heapName;
size_t segment_size;
// StatElement data
size_t alloc_granules;
size_t granule_size;
bool segment_granules;
unsignedint nBlocks_t1;
unsignedint nBlocks_t2;
unsignedint nBlocks_alive;
unsignedint nBlocks_dead;
unsignedint nBlocks_unloaded;
unsignedint nBlocks_stub;
// FreeBlk data
unsignedint alloc_freeBlocks;
// UsedBlk data
unsignedint alloc_topSizeBlocks;
unsignedint used_topSizeBlocks;
// method hotness data. Temperature range is [-reset_val..+reset_val]
int avgTemp;
int maxTemp;
int minTemp;
};
#endif// SHARE_CODE_CODEHEAPSTATE_HPP