Mercurial > hg > graal-compiler
annotate src/share/vm/services/memBaseline.cpp @ 21559:be896a1983c0
recast all Graal native code as JVMCI code (JBS:GRAAL-53)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 28 May 2015 15:36:48 +0200 |
parents | dd3939fe8424 |
children |
rev | line source |
---|---|
6197 | 1 /* |
20360 | 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. |
6197 | 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" | |
20360 | 25 |
6197 | 26 #include "memory/allocation.hpp" |
10148 | 27 #include "runtime/safepoint.hpp" |
28 #include "runtime/thread.inline.hpp" | |
6197 | 29 #include "services/memBaseline.hpp" |
30 #include "services/memTracker.hpp" | |
31 | |
20360 | 32 /* |
33 * Sizes are sorted in descenting order for reporting | |
34 */ | |
35 int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) { | |
36 if (s1.size() == s2.size()) { | |
37 return 0; | |
38 } else if (s1.size() > s2.size()) { | |
39 return -1; | |
40 } else { | |
41 return 1; | |
6197 | 42 } |
43 } | |
44 | |
45 | |
20360 | 46 int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1, |
47 const VirtualMemoryAllocationSite& s2) { | |
48 if (s1.reserved() == s2.reserved()) { | |
49 return 0; | |
50 } else if (s1.reserved() > s2.reserved()) { | |
51 return -1; | |
52 } else { | |
53 return 1; | |
6197 | 54 } |
20360 | 55 } |
6197 | 56 |
20360 | 57 // Sort into allocation site addresses order for baseline comparison |
58 int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) { | |
59 return s1.call_stack()->compare(*s2.call_stack()); | |
6197 | 60 } |
61 | |
62 | |
20360 | 63 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1, |
64 const VirtualMemoryAllocationSite& s2) { | |
65 return s1.call_stack()->compare(*s2.call_stack()); | |
6197 | 66 } |
67 | |
20360 | 68 /* |
69 * Walker to walk malloc allocation site table | |
70 */ | |
71 class MallocAllocationSiteWalker : public MallocSiteWalker { | |
72 private: | |
20366 | 73 SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites; |
20360 | 74 size_t _count; |
75 | |
76 // Entries in MallocSiteTable with size = 0 and count = 0, | |
77 // when the malloc site is not longer there. | |
78 public: | |
20366 | 79 MallocAllocationSiteWalker() : _count(0) { } |
20360 | 80 |
81 inline size_t count() const { return _count; } | |
82 | |
83 LinkedList<MallocSite>* malloc_sites() { | |
84 return &_malloc_sites; | |
85 } | |
86 | |
87 bool do_malloc_site(const MallocSite* site) { | |
88 if (site->size() >= MemBaseline::SIZE_THRESHOLD) { | |
89 if (_malloc_sites.add(*site) != NULL) { | |
90 _count++; | |
91 return true; | |
92 } else { | |
93 return false; // OOM | |
94 } | |
95 } else { | |
96 // malloc site does not meet threshold, ignore and continue | |
97 return true; | |
98 } | |
99 } | |
100 }; | |
101 | |
102 // Compare virtual memory region's base address | |
103 int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) { | |
104 return r1.compare(r2); | |
6197 | 105 } |
106 | |
20360 | 107 // Walk all virtual memory regions for baselining |
108 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { | |
109 private: | |
20366 | 110 SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base> |
20360 | 111 _virtual_memory_regions; |
112 size_t _count; | |
113 | |
114 public: | |
20366 | 115 VirtualMemoryAllocationWalker() : _count(0) { } |
20360 | 116 |
117 bool do_allocation_site(const ReservedMemoryRegion* rgn) { | |
118 if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { | |
119 if (_virtual_memory_regions.add(*rgn) != NULL) { | |
120 _count ++; | |
121 return true; | |
122 } else { | |
123 return false; | |
6197 | 124 } |
125 } | |
20360 | 126 return true; |
6197 | 127 } |
128 | |
20360 | 129 LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() { |
130 return &_virtual_memory_regions; | |
131 } | |
132 }; | |
133 | |
134 | |
135 bool MemBaseline::baseline_summary() { | |
20366 | 136 MallocMemorySummary::snapshot(&_malloc_memory_snapshot); |
137 VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); | |
20360 | 138 return true; |
139 } | |
140 | |
141 bool MemBaseline::baseline_allocation_sites() { | |
142 // Malloc allocation sites | |
20366 | 143 MallocAllocationSiteWalker malloc_walker; |
20360 | 144 if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { |
145 return false; | |
146 } | |
147 | |
20366 | 148 _malloc_sites.move(malloc_walker.malloc_sites()); |
20360 | 149 // The malloc sites are collected in size order |
150 _malloc_sites_order = by_size; | |
151 | |
152 // Virtual memory allocation sites | |
20366 | 153 VirtualMemoryAllocationWalker virtual_memory_walker; |
20360 | 154 if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { |
155 return false; | |
156 } | |
157 | |
158 // Virtual memory allocations are collected in call stack order | |
20366 | 159 _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations()); |
20360 | 160 |
161 if (!aggregate_virtual_memory_allocation_sites()) { | |
162 return false; | |
163 } | |
164 // Virtual memory allocation sites are aggregrated in call stack order | |
165 _virtual_memory_sites_order = by_address; | |
6197 | 166 |
167 return true; | |
168 } | |
169 | |
20360 | 170 bool MemBaseline::baseline(bool summaryOnly) { |
171 reset(); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
172 |
20360 | 173 _class_count = InstanceKlass::number_of_instance_classes(); |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
174 |
20360 | 175 if (!baseline_summary()) { |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
176 return false; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
177 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
178 |
20360 | 179 _baseline_type = Summary_baselined; |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
180 |
20360 | 181 // baseline details |
182 if (!summaryOnly && | |
183 MemTracker::tracking_level() == NMT_detail) { | |
184 baseline_allocation_sites(); | |
185 _baseline_type = Detail_baselined; | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
186 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
187 |
6197 | 188 return true; |
189 } | |
190 | |
20360 | 191 int compare_allocation_site(const VirtualMemoryAllocationSite& s1, |
192 const VirtualMemoryAllocationSite& s2) { | |
193 return s1.call_stack()->compare(*s2.call_stack()); | |
194 } | |
195 | |
196 bool MemBaseline::aggregate_virtual_memory_allocation_sites() { | |
20366 | 197 SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites; |
20360 | 198 |
199 VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); | |
200 const ReservedMemoryRegion* rgn; | |
201 VirtualMemoryAllocationSite* site; | |
202 while ((rgn = itr.next()) != NULL) { | |
203 VirtualMemoryAllocationSite tmp(*rgn->call_stack()); | |
204 site = allocation_sites.find(tmp); | |
205 if (site == NULL) { | |
206 LinkedListNode<VirtualMemoryAllocationSite>* node = | |
207 allocation_sites.add(tmp); | |
208 if (node == NULL) return false; | |
209 site = node->data(); | |
210 } | |
211 site->reserve_memory(rgn->size()); | |
212 site->commit_memory(rgn->committed_size()); | |
10148 | 213 } |
6197 | 214 |
20366 | 215 _virtual_memory_sites.move(&allocation_sites); |
20360 | 216 return true; |
6197 | 217 } |
218 | |
20360 | 219 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { |
20366 | 220 assert(!_malloc_sites.is_empty(), "Not detail baseline"); |
20360 | 221 switch(order) { |
222 case by_size: | |
223 malloc_sites_to_size_order(); | |
224 break; | |
225 case by_site: | |
226 malloc_sites_to_allocation_site_order(); | |
227 break; | |
228 case by_address: | |
229 default: | |
230 ShouldNotReachHere(); | |
6197 | 231 } |
20360 | 232 return MallocSiteIterator(_malloc_sites.head()); |
6197 | 233 } |
234 | |
20360 | 235 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { |
20366 | 236 assert(!_virtual_memory_sites.is_empty(), "Not detail baseline"); |
20360 | 237 switch(order) { |
238 case by_size: | |
239 virtual_memory_sites_to_size_order(); | |
240 break; | |
241 case by_site: | |
242 virtual_memory_sites_to_reservation_site_order(); | |
243 break; | |
244 case by_address: | |
245 default: | |
246 ShouldNotReachHere(); | |
6197 | 247 } |
20360 | 248 return VirtualMemorySiteIterator(_virtual_memory_sites.head()); |
6197 | 249 } |
250 | |
251 | |
20360 | 252 // Sorting allocations sites in different orders |
253 void MemBaseline::malloc_sites_to_size_order() { | |
254 if (_malloc_sites_order != by_size) { | |
20366 | 255 SortedLinkedList<MallocSite, compare_malloc_size> tmp; |
6197 | 256 |
20360 | 257 // Add malloc sites to sorted linked list to sort into size order |
258 tmp.move(&_malloc_sites); | |
259 _malloc_sites.set_head(tmp.head()); | |
260 tmp.set_head(NULL); | |
261 _malloc_sites_order = by_size; | |
6197 | 262 } |
263 } | |
264 | |
20360 | 265 void MemBaseline::malloc_sites_to_allocation_site_order() { |
266 if (_malloc_sites_order != by_site) { | |
20366 | 267 SortedLinkedList<MallocSite, compare_malloc_site> tmp; |
20360 | 268 // Add malloc sites to sorted linked list to sort into site (address) order |
269 tmp.move(&_malloc_sites); | |
270 _malloc_sites.set_head(tmp.head()); | |
271 tmp.set_head(NULL); | |
272 _malloc_sites_order = by_site; | |
273 } | |
6197 | 274 } |
275 | |
20360 | 276 void MemBaseline::virtual_memory_sites_to_size_order() { |
277 if (_virtual_memory_sites_order != by_size) { | |
20366 | 278 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp; |
6197 | 279 |
20360 | 280 tmp.move(&_virtual_memory_sites); |
281 | |
282 _virtual_memory_sites.set_head(tmp.head()); | |
283 tmp.set_head(NULL); | |
284 _virtual_memory_sites_order = by_size; | |
285 } | |
6197 | 286 } |
287 | |
20360 | 288 void MemBaseline::virtual_memory_sites_to_reservation_site_order() { |
289 if (_virtual_memory_sites_order != by_size) { | |
20366 | 290 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp; |
6197 | 291 |
20366 | 292 tmp.move(&_virtual_memory_sites); |
20360 | 293 |
294 _virtual_memory_sites.set_head(tmp.head()); | |
295 tmp.set_head(NULL); | |
296 | |
297 _virtual_memory_sites_order = by_size; | |
298 } | |
6197 | 299 } |
300 |