Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/services/memBaseline.cpp
41144 views
1
/*
2
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
#include "precompiled.hpp"
25
26
#include "classfile/classLoaderDataGraph.inline.hpp"
27
#include "memory/allocation.hpp"
28
#include "memory/metaspaceUtils.hpp"
29
#include "runtime/safepoint.hpp"
30
#include "runtime/thread.inline.hpp"
31
#include "services/memBaseline.hpp"
32
#include "services/memTracker.hpp"
33
34
/*
35
* Sizes are sorted in descenting order for reporting
36
*/
37
int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) {
38
if (s1.size() == s2.size()) {
39
return 0;
40
} else if (s1.size() > s2.size()) {
41
return -1;
42
} else {
43
return 1;
44
}
45
}
46
47
48
int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1,
49
const VirtualMemoryAllocationSite& s2) {
50
if (s1.reserved() == s2.reserved()) {
51
return 0;
52
} else if (s1.reserved() > s2.reserved()) {
53
return -1;
54
} else {
55
return 1;
56
}
57
}
58
59
// Sort into allocation site addresses order for baseline comparison
60
int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) {
61
return s1.call_stack()->compare(*s2.call_stack());
62
}
63
64
// Sort into allocation site addresses and memory type order for baseline comparison
65
int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) {
66
int res = compare_malloc_site(s1, s2);
67
if (res == 0) {
68
res = (int)(NMTUtil::flag_to_index(s1.flag()) - NMTUtil::flag_to_index(s2.flag()));
69
}
70
71
return res;
72
}
73
74
int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,
75
const VirtualMemoryAllocationSite& s2) {
76
return s1.call_stack()->compare(*s2.call_stack());
77
}
78
79
/*
80
* Walker to walk malloc allocation site table
81
*/
82
class MallocAllocationSiteWalker : public MallocSiteWalker {
83
private:
84
SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;
85
size_t _count;
86
87
// Entries in MallocSiteTable with size = 0 and count = 0,
88
// when the malloc site is not longer there.
89
public:
90
MallocAllocationSiteWalker() : _count(0) { }
91
92
inline size_t count() const { return _count; }
93
94
LinkedList<MallocSite>* malloc_sites() {
95
return &_malloc_sites;
96
}
97
98
bool do_malloc_site(const MallocSite* site) {
99
if (site->size() > 0) {
100
if (_malloc_sites.add(*site) != NULL) {
101
_count++;
102
return true;
103
} else {
104
return false; // OOM
105
}
106
} else {
107
// Ignore empty sites.
108
return true;
109
}
110
}
111
};
112
113
// Compare virtual memory region's base address
114
int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {
115
return r1.compare(r2);
116
}
117
118
// Walk all virtual memory regions for baselining
119
class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
120
private:
121
SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>
122
_virtual_memory_regions;
123
size_t _count;
124
125
public:
126
VirtualMemoryAllocationWalker() : _count(0) { }
127
128
bool do_allocation_site(const ReservedMemoryRegion* rgn) {
129
if (rgn->size() > 0) {
130
if (_virtual_memory_regions.add(*rgn) != NULL) {
131
_count ++;
132
return true;
133
} else {
134
return false;
135
}
136
} else {
137
// Ignore empty sites.
138
return true;
139
}
140
}
141
142
LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {
143
return &_virtual_memory_regions;
144
}
145
};
146
147
148
bool MemBaseline::baseline_summary() {
149
MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
150
VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
151
_metaspace_stats = MetaspaceUtils::get_combined_statistics();
152
return true;
153
}
154
155
bool MemBaseline::baseline_allocation_sites() {
156
// Malloc allocation sites
157
MallocAllocationSiteWalker malloc_walker;
158
if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {
159
return false;
160
}
161
162
// Walk simple thread stacks
163
if (!ThreadStackTracker::walk_simple_thread_stack_site(&malloc_walker)) {
164
return false;
165
}
166
167
_malloc_sites.move(malloc_walker.malloc_sites());
168
// The malloc sites are collected in size order
169
_malloc_sites_order = by_size;
170
171
// Virtual memory allocation sites
172
VirtualMemoryAllocationWalker virtual_memory_walker;
173
if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {
174
return false;
175
}
176
177
// Virtual memory allocations are collected in call stack order
178
_virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
179
180
if (!aggregate_virtual_memory_allocation_sites()) {
181
return false;
182
}
183
// Virtual memory allocation sites are aggregrated in call stack order
184
_virtual_memory_sites_order = by_address;
185
186
return true;
187
}
188
189
bool MemBaseline::baseline(bool summaryOnly) {
190
reset();
191
192
_instance_class_count = ClassLoaderDataGraph::num_instance_classes();
193
_array_class_count = ClassLoaderDataGraph::num_array_classes();
194
195
if (!baseline_summary()) {
196
return false;
197
}
198
199
_baseline_type = Summary_baselined;
200
201
// baseline details
202
if (!summaryOnly &&
203
MemTracker::tracking_level() == NMT_detail) {
204
baseline_allocation_sites();
205
_baseline_type = Detail_baselined;
206
}
207
208
return true;
209
}
210
211
int compare_allocation_site(const VirtualMemoryAllocationSite& s1,
212
const VirtualMemoryAllocationSite& s2) {
213
return s1.call_stack()->compare(*s2.call_stack());
214
}
215
216
bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
217
SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
218
219
VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
220
const ReservedMemoryRegion* rgn;
221
VirtualMemoryAllocationSite* site;
222
while ((rgn = itr.next()) != NULL) {
223
VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag());
224
site = allocation_sites.find(tmp);
225
if (site == NULL) {
226
LinkedListNode<VirtualMemoryAllocationSite>* node =
227
allocation_sites.add(tmp);
228
if (node == NULL) return false;
229
site = node->data();
230
}
231
site->reserve_memory(rgn->size());
232
site->commit_memory(rgn->committed_size());
233
}
234
235
_virtual_memory_sites.move(&allocation_sites);
236
return true;
237
}
238
239
MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
240
assert(!_malloc_sites.is_empty(), "Not detail baseline");
241
switch(order) {
242
case by_size:
243
malloc_sites_to_size_order();
244
break;
245
case by_site:
246
malloc_sites_to_allocation_site_order();
247
break;
248
case by_site_and_type:
249
malloc_sites_to_allocation_site_and_type_order();
250
break;
251
case by_address:
252
default:
253
ShouldNotReachHere();
254
}
255
return MallocSiteIterator(_malloc_sites.head());
256
}
257
258
VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {
259
assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");
260
switch(order) {
261
case by_size:
262
virtual_memory_sites_to_size_order();
263
break;
264
case by_site:
265
virtual_memory_sites_to_reservation_site_order();
266
break;
267
case by_address:
268
default:
269
ShouldNotReachHere();
270
}
271
return VirtualMemorySiteIterator(_virtual_memory_sites.head());
272
}
273
274
275
// Sorting allocations sites in different orders
276
void MemBaseline::malloc_sites_to_size_order() {
277
if (_malloc_sites_order != by_size) {
278
SortedLinkedList<MallocSite, compare_malloc_size> tmp;
279
280
// Add malloc sites to sorted linked list to sort into size order
281
tmp.move(&_malloc_sites);
282
_malloc_sites.set_head(tmp.head());
283
tmp.set_head(NULL);
284
_malloc_sites_order = by_size;
285
}
286
}
287
288
void MemBaseline::malloc_sites_to_allocation_site_order() {
289
if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) {
290
SortedLinkedList<MallocSite, compare_malloc_site> tmp;
291
// Add malloc sites to sorted linked list to sort into site (address) order
292
tmp.move(&_malloc_sites);
293
_malloc_sites.set_head(tmp.head());
294
tmp.set_head(NULL);
295
_malloc_sites_order = by_site;
296
}
297
}
298
299
void MemBaseline::malloc_sites_to_allocation_site_and_type_order() {
300
if (_malloc_sites_order != by_site_and_type) {
301
SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp;
302
// Add malloc sites to sorted linked list to sort into site (address) order
303
tmp.move(&_malloc_sites);
304
_malloc_sites.set_head(tmp.head());
305
tmp.set_head(NULL);
306
_malloc_sites_order = by_site_and_type;
307
}
308
}
309
310
void MemBaseline::virtual_memory_sites_to_size_order() {
311
if (_virtual_memory_sites_order != by_size) {
312
SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
313
314
tmp.move(&_virtual_memory_sites);
315
316
_virtual_memory_sites.set_head(tmp.head());
317
tmp.set_head(NULL);
318
_virtual_memory_sites_order = by_size;
319
}
320
}
321
322
void MemBaseline::virtual_memory_sites_to_reservation_site_order() {
323
if (_virtual_memory_sites_order != by_size) {
324
SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;
325
326
tmp.move(&_virtual_memory_sites);
327
328
_virtual_memory_sites.set_head(tmp.head());
329
tmp.set_head(NULL);
330
331
_virtual_memory_sites_order = by_size;
332
}
333
}
334
335
336