Mercurial > hg > truffle
annotate src/share/vm/code/codeCache.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | aff6ccb506cb |
children | 7848fc12602b |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/codeBlob.hpp" | |
27 #include "code/codeCache.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
28 #include "code/compiledIC.hpp" |
1972 | 29 #include "code/dependencies.hpp" |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
30 #include "code/icBuffer.hpp" |
1972 | 31 #include "code/nmethod.hpp" |
32 #include "code/pcDesc.hpp" | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
33 #include "compiler/compileBroker.hpp" |
1972 | 34 #include "gc_implementation/shared/markSweep.hpp" |
35 #include "memory/allocation.inline.hpp" | |
36 #include "memory/gcLocker.hpp" | |
37 #include "memory/iterator.hpp" | |
38 #include "memory/resourceArea.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
39 #include "oops/method.hpp" |
1972 | 40 #include "oops/objArrayOop.hpp" |
41 #include "oops/oop.inline.hpp" | |
42 #include "runtime/handles.inline.hpp" | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
43 #include "runtime/arguments.hpp" |
1972 | 44 #include "runtime/icache.hpp" |
45 #include "runtime/java.hpp" | |
46 #include "runtime/mutexLocker.hpp" | |
47 #include "services/memoryService.hpp" | |
10405 | 48 #include "trace/tracing.hpp" |
1972 | 49 #include "utilities/xmlstream.hpp" |
0 | 50 |
51 // Helper class for printing in CodeCache | |
52 | |
53 class CodeBlob_sizes { | |
54 private: | |
55 int count; | |
56 int total_size; | |
57 int header_size; | |
58 int code_size; | |
59 int stub_size; | |
60 int relocation_size; | |
61 int scopes_oop_size; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
62 int scopes_metadata_size; |
0 | 63 int scopes_data_size; |
64 int scopes_pcs_size; | |
65 | |
66 public: | |
67 CodeBlob_sizes() { | |
68 count = 0; | |
69 total_size = 0; | |
70 header_size = 0; | |
71 code_size = 0; | |
72 stub_size = 0; | |
73 relocation_size = 0; | |
74 scopes_oop_size = 0; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
75 scopes_metadata_size = 0; |
0 | 76 scopes_data_size = 0; |
77 scopes_pcs_size = 0; | |
78 } | |
79 | |
80 int total() { return total_size; } | |
81 bool is_empty() { return count == 0; } | |
82 | |
83 void print(const char* title) { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
84 tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])", |
0 | 85 count, |
86 title, | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
87 (int)(total() / K), |
0 | 88 header_size * 100 / total_size, |
89 relocation_size * 100 / total_size, | |
90 code_size * 100 / total_size, | |
91 stub_size * 100 / total_size, | |
92 scopes_oop_size * 100 / total_size, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
93 scopes_metadata_size * 100 / total_size, |
0 | 94 scopes_data_size * 100 / total_size, |
95 scopes_pcs_size * 100 / total_size); | |
96 } | |
97 | |
98 void add(CodeBlob* cb) { | |
99 count++; | |
100 total_size += cb->size(); | |
101 header_size += cb->header_size(); | |
102 relocation_size += cb->relocation_size(); | |
103 if (cb->is_nmethod()) { | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
104 nmethod* nm = cb->as_nmethod_or_null(); |
1748 | 105 code_size += nm->insts_size(); |
0 | 106 stub_size += nm->stub_size(); |
107 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
108 scopes_oop_size += nm->oops_size(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
109 scopes_metadata_size += nm->metadata_size(); |
0 | 110 scopes_data_size += nm->scopes_data_size(); |
111 scopes_pcs_size += nm->scopes_pcs_size(); | |
112 } else { | |
1748 | 113 code_size += cb->code_size(); |
0 | 114 } |
115 } | |
116 }; | |
117 | |
118 // CodeCache implementation | |
119 | |
120 CodeHeap * CodeCache::_heap = new CodeHeap(); | |
121 int CodeCache::_number_of_blobs = 0; | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
122 int CodeCache::_number_of_adapters = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
123 int CodeCache::_number_of_nmethods = 0; |
0 | 124 int CodeCache::_number_of_nmethods_with_dependencies = 0; |
125 bool CodeCache::_needs_cache_clean = false; | |
989 | 126 nmethod* CodeCache::_scavenge_root_nmethods = NULL; |
0 | 127 |
10405 | 128 int CodeCache::_codemem_full_count = 0; |
0 | 129 |
130 CodeBlob* CodeCache::first() { | |
131 assert_locked_or_safepoint(CodeCache_lock); | |
132 return (CodeBlob*)_heap->first(); | |
133 } | |
134 | |
135 | |
136 CodeBlob* CodeCache::next(CodeBlob* cb) { | |
137 assert_locked_or_safepoint(CodeCache_lock); | |
138 return (CodeBlob*)_heap->next(cb); | |
139 } | |
140 | |
141 | |
142 CodeBlob* CodeCache::alive(CodeBlob *cb) { | |
143 assert_locked_or_safepoint(CodeCache_lock); | |
144 while (cb != NULL && !cb->is_alive()) cb = next(cb); | |
145 return cb; | |
146 } | |
147 | |
148 | |
149 nmethod* CodeCache::alive_nmethod(CodeBlob* cb) { | |
150 assert_locked_or_safepoint(CodeCache_lock); | |
151 while (cb != NULL && (!cb->is_alive() || !cb->is_nmethod())) cb = next(cb); | |
152 return (nmethod*)cb; | |
153 } | |
154 | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
155 nmethod* CodeCache::first_nmethod() { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
156 assert_locked_or_safepoint(CodeCache_lock); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
157 CodeBlob* cb = first(); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
158 while (cb != NULL && !cb->is_nmethod()) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
159 cb = next(cb); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
160 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
161 return (nmethod*)cb; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
162 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
163 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
164 nmethod* CodeCache::next_nmethod (CodeBlob* cb) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
165 assert_locked_or_safepoint(CodeCache_lock); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
166 cb = next(cb); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
167 while (cb != NULL && !cb->is_nmethod()) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
168 cb = next(cb); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
169 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
170 return (nmethod*)cb; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1363
diff
changeset
|
171 } |
0 | 172 |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
173 static size_t maxCodeCacheUsed = 0; |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
174 |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
175 CodeBlob* CodeCache::allocate(int size, bool is_critical) { |
0 | 176 // Do not seize the CodeCache lock here--if the caller has not |
177 // already done so, we are going to lose bigtime, since the code | |
178 // cache will contain a garbage CodeBlob until the caller can | |
179 // run the constructor for the CodeBlob subclass he is busy | |
180 // instantiating. | |
181 guarantee(size >= 0, "allocation request must be reasonable"); | |
182 assert_locked_or_safepoint(CodeCache_lock); | |
183 CodeBlob* cb = NULL; | |
184 _number_of_blobs++; | |
185 while (true) { | |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
186 cb = (CodeBlob*)_heap->allocate(size, is_critical); |
0 | 187 if (cb != NULL) break; |
188 if (!_heap->expand_by(CodeCacheExpansionSize)) { | |
189 // Expansion failed | |
190 return NULL; | |
191 } | |
192 if (PrintCodeCacheExtension) { | |
193 ResourceMark rm; | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
194 tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (" SSIZE_FORMAT " bytes)", |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
195 (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(), |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
196 (address)_heap->high() - (address)_heap->low_boundary()); |
0 | 197 } |
198 } | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
199 maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
200 (address)_heap->low_boundary()) - unallocated_capacity()); |
0 | 201 verify_if_often(); |
989 | 202 print_trace("allocation", cb, size); |
0 | 203 return cb; |
204 } | |
205 | |
206 void CodeCache::free(CodeBlob* cb) { | |
207 assert_locked_or_safepoint(CodeCache_lock); | |
208 verify_if_often(); | |
209 | |
989 | 210 print_trace("free", cb); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
211 if (cb->is_nmethod()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
212 _number_of_nmethods--; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
213 if (((nmethod *)cb)->has_dependencies()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
214 _number_of_nmethods_with_dependencies--; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
215 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
216 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
217 if (cb->is_adapter_blob()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
218 _number_of_adapters--; |
0 | 219 } |
220 _number_of_blobs--; | |
221 | |
222 _heap->deallocate(cb); | |
223 | |
224 verify_if_often(); | |
225 assert(_number_of_blobs >= 0, "sanity check"); | |
226 } | |
227 | |
228 | |
229 void CodeCache::commit(CodeBlob* cb) { | |
230 // this is called by nmethod::nmethod, which must already own CodeCache_lock | |
231 assert_locked_or_safepoint(CodeCache_lock); | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
232 if (cb->is_nmethod()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
233 _number_of_nmethods++; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
234 if (((nmethod *)cb)->has_dependencies()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
235 _number_of_nmethods_with_dependencies++; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
236 } |
0 | 237 } |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
238 if (cb->is_adapter_blob()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
239 _number_of_adapters++; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
240 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1579
diff
changeset
|
241 |
0 | 242 // flush the hardware I-cache |
1748 | 243 ICache::invalidate_range(cb->content_begin(), cb->content_size()); |
0 | 244 } |
245 | |
246 | |
247 void CodeCache::flush() { | |
248 assert_locked_or_safepoint(CodeCache_lock); | |
249 Unimplemented(); | |
250 } | |
251 | |
252 | |
253 // Iteration over CodeBlobs | |
254 | |
255 #define FOR_ALL_BLOBS(var) for (CodeBlob *var = first() ; var != NULL; var = next(var) ) | |
256 #define FOR_ALL_ALIVE_BLOBS(var) for (CodeBlob *var = alive(first()); var != NULL; var = alive(next(var))) | |
257 #define FOR_ALL_ALIVE_NMETHODS(var) for (nmethod *var = alive_nmethod(first()); var != NULL; var = alive_nmethod(next(var))) | |
258 | |
259 | |
260 bool CodeCache::contains(void *p) { | |
261 // It should be ok to call contains without holding a lock | |
262 return _heap->contains(p); | |
263 } | |
264 | |
265 | |
266 // This method is safe to call without holding the CodeCache_lock, as long as a dead codeblob is not | |
267 // looked up (i.e., one that has been marked for deletion). It only dependes on the _segmap to contain | |
268 // valid indices, which it will always do, as long as the CodeBlob is not in the process of being recycled. | |
269 CodeBlob* CodeCache::find_blob(void* start) { | |
270 CodeBlob* result = find_blob_unsafe(start); | |
271 if (result == NULL) return NULL; | |
272 // We could potientially look up non_entrant methods | |
273 guarantee(!result->is_zombie() || result->is_locked_by_vm() || is_error_reported(), "unsafe access to zombie method"); | |
274 return result; | |
275 } | |
276 | |
277 nmethod* CodeCache::find_nmethod(void* start) { | |
278 CodeBlob *cb = find_blob(start); | |
279 assert(cb == NULL || cb->is_nmethod(), "did not find an nmethod"); | |
280 return (nmethod*)cb; | |
281 } | |
282 | |
283 | |
284 void CodeCache::blobs_do(void f(CodeBlob* nm)) { | |
285 assert_locked_or_safepoint(CodeCache_lock); | |
286 FOR_ALL_BLOBS(p) { | |
287 f(p); | |
288 } | |
289 } | |
290 | |
291 | |
292 void CodeCache::nmethods_do(void f(nmethod* nm)) { | |
293 assert_locked_or_safepoint(CodeCache_lock); | |
294 FOR_ALL_BLOBS(nm) { | |
295 if (nm->is_nmethod()) f((nmethod*)nm); | |
296 } | |
297 } | |
298 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
299 void CodeCache::alive_nmethods_do(void f(nmethod* nm)) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
300 assert_locked_or_safepoint(CodeCache_lock); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
301 FOR_ALL_ALIVE_NMETHODS(nm) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
302 f(nm); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
303 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
304 } |
0 | 305 |
306 int CodeCache::alignment_unit() { | |
307 return (int)_heap->alignment_unit(); | |
308 } | |
309 | |
310 | |
311 int CodeCache::alignment_offset() { | |
312 return (int)_heap->alignment_offset(); | |
313 } | |
314 | |
315 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
316 // Mark nmethods for unloading if they contain otherwise unreachable |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
317 // oops. |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
318 void CodeCache::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) { |
0 | 319 assert_locked_or_safepoint(CodeCache_lock); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
320 FOR_ALL_ALIVE_NMETHODS(nm) { |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
321 nm->do_unloading(is_alive, unloading_occurred); |
0 | 322 } |
323 } | |
324 | |
989 | 325 void CodeCache::blobs_do(CodeBlobClosure* f) { |
0 | 326 assert_locked_or_safepoint(CodeCache_lock); |
327 FOR_ALL_ALIVE_BLOBS(cb) { | |
989 | 328 f->do_code_blob(cb); |
329 | |
330 #ifdef ASSERT | |
331 if (cb->is_nmethod()) | |
332 ((nmethod*)cb)->verify_scavenge_root_oops(); | |
333 #endif //ASSERT | |
0 | 334 } |
335 } | |
336 | |
989 | 337 // Walk the list of methods which might contain non-perm oops. |
338 void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) { | |
339 assert_locked_or_safepoint(CodeCache_lock); | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
340 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
341 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
342 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
343 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
344 |
989 | 345 debug_only(mark_scavenge_root_nmethods()); |
346 | |
347 for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { | |
348 debug_only(cur->clear_scavenge_root_marked()); | |
349 assert(cur->scavenge_root_not_marked(), ""); | |
350 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); | |
351 | |
352 bool is_live = (!cur->is_zombie() && !cur->is_unloaded()); | |
353 #ifndef PRODUCT | |
354 if (TraceScavenge) { | |
355 cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr(); | |
356 } | |
357 #endif //PRODUCT | |
1363
ed4f78aa9282
6940520: CodeCache::scavenge_root_nmethods_do must fix oop relocations
twisti
parents:
1202
diff
changeset
|
358 if (is_live) { |
989 | 359 // Perform cur->oops_do(f), maybe just once per nmethod. |
360 f->do_code_blob(cur); | |
1363
ed4f78aa9282
6940520: CodeCache::scavenge_root_nmethods_do must fix oop relocations
twisti
parents:
1202
diff
changeset
|
361 } |
989 | 362 } |
363 | |
364 // Check for stray marks. | |
365 debug_only(verify_perm_nmethods(NULL)); | |
366 } | |
367 | |
368 void CodeCache::add_scavenge_root_nmethod(nmethod* nm) { | |
369 assert_locked_or_safepoint(CodeCache_lock); | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
370 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
371 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
372 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
373 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
374 |
989 | 375 nm->set_on_scavenge_root_list(); |
376 nm->set_scavenge_root_link(_scavenge_root_nmethods); | |
377 set_scavenge_root_nmethods(nm); | |
378 print_trace("add_scavenge_root", nm); | |
379 } | |
380 | |
381 void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) { | |
382 assert_locked_or_safepoint(CodeCache_lock); | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
383 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
384 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
385 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
386 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
387 |
989 | 388 print_trace("drop_scavenge_root", nm); |
389 nmethod* last = NULL; | |
390 nmethod* cur = scavenge_root_nmethods(); | |
391 while (cur != NULL) { | |
392 nmethod* next = cur->scavenge_root_link(); | |
393 if (cur == nm) { | |
394 if (last != NULL) | |
395 last->set_scavenge_root_link(next); | |
396 else set_scavenge_root_nmethods(next); | |
397 nm->set_scavenge_root_link(NULL); | |
398 nm->clear_on_scavenge_root_list(); | |
399 return; | |
400 } | |
401 last = cur; | |
402 cur = next; | |
403 } | |
404 assert(false, "should have been on list"); | |
405 } | |
406 | |
407 void CodeCache::prune_scavenge_root_nmethods() { | |
408 assert_locked_or_safepoint(CodeCache_lock); | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
409 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
410 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
411 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
412 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
413 |
989 | 414 debug_only(mark_scavenge_root_nmethods()); |
415 | |
416 nmethod* last = NULL; | |
417 nmethod* cur = scavenge_root_nmethods(); | |
418 while (cur != NULL) { | |
419 nmethod* next = cur->scavenge_root_link(); | |
420 debug_only(cur->clear_scavenge_root_marked()); | |
421 assert(cur->scavenge_root_not_marked(), ""); | |
422 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); | |
423 | |
424 if (!cur->is_zombie() && !cur->is_unloaded() | |
425 && cur->detect_scavenge_root_oops()) { | |
426 // Keep it. Advance 'last' to prevent deletion. | |
427 last = cur; | |
428 } else { | |
429 // Prune it from the list, so we don't have to look at it any more. | |
430 print_trace("prune_scavenge_root", cur); | |
431 cur->set_scavenge_root_link(NULL); | |
432 cur->clear_on_scavenge_root_list(); | |
433 if (last != NULL) | |
434 last->set_scavenge_root_link(next); | |
435 else set_scavenge_root_nmethods(next); | |
436 } | |
437 cur = next; | |
438 } | |
439 | |
440 // Check for stray marks. | |
441 debug_only(verify_perm_nmethods(NULL)); | |
442 } | |
443 | |
444 #ifndef PRODUCT | |
445 void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) { | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
446 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
447 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
448 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
449 |
989 | 450 // While we are here, verify the integrity of the list. |
451 mark_scavenge_root_nmethods(); | |
452 for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { | |
453 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); | |
454 cur->clear_scavenge_root_marked(); | |
455 } | |
456 verify_perm_nmethods(f); | |
457 } | |
458 | |
459 // Temporarily mark nmethods that are claimed to be on the non-perm list. | |
460 void CodeCache::mark_scavenge_root_nmethods() { | |
461 FOR_ALL_ALIVE_BLOBS(cb) { | |
462 if (cb->is_nmethod()) { | |
463 nmethod *nm = (nmethod*)cb; | |
464 assert(nm->scavenge_root_not_marked(), "clean state"); | |
465 if (nm->on_scavenge_root_list()) | |
466 nm->set_scavenge_root_marked(); | |
467 } | |
468 } | |
469 } | |
470 | |
471 // If the closure is given, run it on the unlisted nmethods. | |
472 // Also make sure that the effects of mark_scavenge_root_nmethods is gone. | |
473 void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) { | |
474 FOR_ALL_ALIVE_BLOBS(cb) { | |
475 bool call_f = (f_or_null != NULL); | |
476 if (cb->is_nmethod()) { | |
477 nmethod *nm = (nmethod*)cb; | |
478 assert(nm->scavenge_root_not_marked(), "must be already processed"); | |
479 if (nm->on_scavenge_root_list()) | |
480 call_f = false; // don't show this one to the client | |
481 nm->verify_scavenge_root_oops(); | |
482 } else { | |
483 call_f = false; // not an nmethod | |
484 } | |
485 if (call_f) f_or_null->do_code_blob(cb); | |
486 } | |
487 } | |
488 #endif //PRODUCT | |
489 | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
490 void CodeCache::verify_clean_inline_caches() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
491 #ifdef ASSERT |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
492 FOR_ALL_ALIVE_BLOBS(cb) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
493 if (cb->is_nmethod()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
494 nmethod* nm = (nmethod*)cb; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
495 assert(!nm->is_unloaded(), "Tautology"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
496 nm->verify_clean_inline_caches(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
497 nm->verify(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
498 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
499 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
500 #endif |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
501 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
502 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
503 void CodeCache::verify_icholder_relocations() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
504 #ifdef ASSERT |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
505 // make sure that we aren't leaking icholders |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
506 int count = 0; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
507 FOR_ALL_BLOBS(cb) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
508 if (cb->is_nmethod()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
509 nmethod* nm = (nmethod*)cb; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
510 count += nm->verify_icholder_relocations(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
511 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
512 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
513 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
514 assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() == |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
515 CompiledICHolder::live_count(), "must agree"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
516 #endif |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
517 } |
1202 | 518 |
0 | 519 void CodeCache::gc_prologue() { |
520 } | |
521 | |
522 void CodeCache::gc_epilogue() { | |
523 assert_locked_or_safepoint(CodeCache_lock); | |
524 FOR_ALL_ALIVE_BLOBS(cb) { | |
525 if (cb->is_nmethod()) { | |
526 nmethod *nm = (nmethod*)cb; | |
527 assert(!nm->is_unloaded(), "Tautology"); | |
528 if (needs_cache_clean()) { | |
529 nm->cleanup_inline_caches(); | |
530 } | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
531 DEBUG_ONLY(nm->verify()); |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
532 DEBUG_ONLY(nm->verify_oop_relocations()); |
0 | 533 } |
534 } | |
535 set_needs_cache_clean(false); | |
989 | 536 prune_scavenge_root_nmethods(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
537 |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
538 verify_icholder_relocations(); |
0 | 539 } |
540 | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
541 void CodeCache::verify_oops() { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
542 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
543 VerifyOopClosure voc; |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
544 FOR_ALL_ALIVE_BLOBS(cb) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
545 if (cb->is_nmethod()) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
546 nmethod *nm = (nmethod*)cb; |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
547 nm->oops_do(&voc); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
548 nm->verify_oop_relocations(); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
549 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
550 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
551 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
552 |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2353
diff
changeset
|
553 |
0 | 554 address CodeCache::first_address() { |
555 assert_locked_or_safepoint(CodeCache_lock); | |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
556 return (address)_heap->low_boundary(); |
0 | 557 } |
558 | |
559 | |
560 address CodeCache::last_address() { | |
561 assert_locked_or_safepoint(CodeCache_lock); | |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
562 return (address)_heap->high(); |
0 | 563 } |
564 | |
10319
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
565 /** |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
566 * Returns the reverse free ratio. E.g., if 25% (1/4) of the code cache |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
567 * is free, reverse_free_ratio() returns 4. |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
568 */ |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
569 double CodeCache::reverse_free_ratio() { |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
570 double unallocated_capacity = (double)(CodeCache::unallocated_capacity() - CodeCacheMinimumFreeSpace); |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
571 double max_capacity = (double)CodeCache::max_capacity(); |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
572 return max_capacity / unallocated_capacity; |
91eba9f82325
8012371: Adjust Tiered compile threshold according to available space in code cache
anoll
parents:
10206
diff
changeset
|
573 } |
0 | 574 |
575 void icache_init(); | |
576 | |
577 void CodeCache::initialize() { | |
578 assert(CodeCacheSegmentSize >= (uintx)CodeEntryAlignment, "CodeCacheSegmentSize must be large enough to align entry points"); | |
579 #ifdef COMPILER2 | |
580 assert(CodeCacheSegmentSize >= (uintx)OptoLoopAlignment, "CodeCacheSegmentSize must be large enough to align inner loops"); | |
581 #endif | |
582 assert(CodeCacheSegmentSize >= sizeof(jdouble), "CodeCacheSegmentSize must be large enough to align constants"); | |
583 // This was originally just a check of the alignment, causing failure, instead, round | |
584 // the code cache to the page size. In particular, Solaris is moving to a larger | |
585 // default page size. | |
586 CodeCacheExpansionSize = round_to(CodeCacheExpansionSize, os::vm_page_size()); | |
587 InitialCodeCacheSize = round_to(InitialCodeCacheSize, os::vm_page_size()); | |
588 ReservedCodeCacheSize = round_to(ReservedCodeCacheSize, os::vm_page_size()); | |
589 if (!_heap->reserve(ReservedCodeCacheSize, InitialCodeCacheSize, CodeCacheSegmentSize)) { | |
590 vm_exit_during_initialization("Could not reserve enough space for code cache"); | |
591 } | |
592 | |
593 MemoryService::add_code_heap_memory_pool(_heap); | |
594 | |
595 // Initialize ICache flush mechanism | |
596 // This service is needed for os::register_code_area | |
597 icache_init(); | |
598 | |
599 // Give OS a chance to register generated code area. | |
600 // This is used on Windows 64 bit platforms to register | |
601 // Structured Exception Handlers for our generated code. | |
602 os::register_code_area(_heap->low_boundary(), _heap->high_boundary()); | |
603 } | |
604 | |
605 | |
606 void codeCache_init() { | |
607 CodeCache::initialize(); | |
608 } | |
609 | |
610 //------------------------------------------------------------------------------------------------ | |
611 | |
612 int CodeCache::number_of_nmethods_with_dependencies() { | |
613 return _number_of_nmethods_with_dependencies; | |
614 } | |
615 | |
616 void CodeCache::clear_inline_caches() { | |
617 assert_locked_or_safepoint(CodeCache_lock); | |
618 FOR_ALL_ALIVE_NMETHODS(nm) { | |
619 nm->clear_inline_caches(); | |
620 } | |
621 } | |
622 | |
623 #ifndef PRODUCT | |
624 // used to keep track of how much time is spent in mark_for_deoptimization | |
625 static elapsedTimer dependentCheckTime; | |
626 static int dependentCheckCount = 0; | |
627 #endif // PRODUCT | |
628 | |
629 | |
630 int CodeCache::mark_for_deoptimization(DepChange& changes) { | |
631 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
632 | |
633 #ifndef PRODUCT | |
634 dependentCheckTime.start(); | |
635 dependentCheckCount++; | |
636 #endif // PRODUCT | |
637 | |
638 int number_of_marked_CodeBlobs = 0; | |
639 | |
640 // search the hierarchy looking for nmethods which are affected by the loading of this class | |
641 | |
642 // then search the interfaces this class implements looking for nmethods | |
643 // which might be dependent of the fact that an interface only had one | |
644 // implementor. | |
645 | |
646 { No_Safepoint_Verifier nsv; | |
647 for (DepChange::ContextStream str(changes, nsv); str.next(); ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
648 Klass* d = str.klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
649 number_of_marked_CodeBlobs += InstanceKlass::cast(d)->mark_dependent_nmethods(changes); |
0 | 650 } |
651 } | |
652 | |
653 if (VerifyDependencies) { | |
654 // Turn off dependency tracing while actually testing deps. | |
655 NOT_PRODUCT( FlagSetting fs(TraceDependencies, false) ); | |
656 FOR_ALL_ALIVE_NMETHODS(nm) { | |
657 if (!nm->is_marked_for_deoptimization() && | |
658 nm->check_all_dependencies()) { | |
659 ResourceMark rm; | |
660 tty->print_cr("Should have been marked for deoptimization:"); | |
661 changes.print(); | |
662 nm->print(); | |
663 nm->print_dependencies(); | |
664 } | |
665 } | |
666 } | |
667 | |
668 #ifndef PRODUCT | |
669 dependentCheckTime.stop(); | |
670 #endif // PRODUCT | |
671 | |
672 return number_of_marked_CodeBlobs; | |
673 } | |
674 | |
675 | |
676 #ifdef HOTSWAP | |
677 int CodeCache::mark_for_evol_deoptimization(instanceKlassHandle dependee) { | |
678 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
679 int number_of_marked_CodeBlobs = 0; | |
680 | |
681 // Deoptimize all methods of the evolving class itself | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
682 Array<Method*>* old_methods = dependee->methods(); |
0 | 683 for (int i = 0; i < old_methods->length(); i++) { |
684 ResourceMark rm; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
685 Method* old_method = old_methods->at(i); |
0 | 686 nmethod *nm = old_method->code(); |
687 if (nm != NULL) { | |
688 nm->mark_for_deoptimization(); | |
689 number_of_marked_CodeBlobs++; | |
690 } | |
691 } | |
692 | |
693 FOR_ALL_ALIVE_NMETHODS(nm) { | |
694 if (nm->is_marked_for_deoptimization()) { | |
695 // ...Already marked in the previous pass; don't count it again. | |
696 } else if (nm->is_evol_dependent_on(dependee())) { | |
697 ResourceMark rm; | |
698 nm->mark_for_deoptimization(); | |
699 number_of_marked_CodeBlobs++; | |
700 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
701 // flush caches in case they refer to a redefined Method* |
0 | 702 nm->clear_inline_caches(); |
703 } | |
704 } | |
705 | |
706 return number_of_marked_CodeBlobs; | |
707 } | |
708 #endif // HOTSWAP | |
709 | |
710 | |
711 // Deoptimize all methods | |
712 void CodeCache::mark_all_nmethods_for_deoptimization() { | |
713 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
714 FOR_ALL_ALIVE_NMETHODS(nm) { | |
20432
aff6ccb506cb
8056154: JVM crash with EXCEPTION_ACCESS_VIOLATION when there are many threads running
iveresov
parents:
20278
diff
changeset
|
715 if (!nm->method()->is_method_handle_intrinsic()) { |
aff6ccb506cb
8056154: JVM crash with EXCEPTION_ACCESS_VIOLATION when there are many threads running
iveresov
parents:
20278
diff
changeset
|
716 nm->mark_for_deoptimization(); |
aff6ccb506cb
8056154: JVM crash with EXCEPTION_ACCESS_VIOLATION when there are many threads running
iveresov
parents:
20278
diff
changeset
|
717 } |
0 | 718 } |
719 } | |
720 | |
721 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
722 int CodeCache::mark_for_deoptimization(Method* dependee) { |
0 | 723 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
724 int number_of_marked_CodeBlobs = 0; | |
725 | |
726 FOR_ALL_ALIVE_NMETHODS(nm) { | |
727 if (nm->is_dependent_on_method(dependee)) { | |
728 ResourceMark rm; | |
729 nm->mark_for_deoptimization(); | |
730 number_of_marked_CodeBlobs++; | |
731 } | |
732 } | |
733 | |
734 return number_of_marked_CodeBlobs; | |
735 } | |
736 | |
737 void CodeCache::make_marked_nmethods_zombies() { | |
738 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
739 FOR_ALL_ALIVE_NMETHODS(nm) { | |
740 if (nm->is_marked_for_deoptimization()) { | |
741 | |
742 // If the nmethod has already been made non-entrant and it can be converted | |
743 // then zombie it now. Otherwise make it non-entrant and it will eventually | |
744 // be zombied when it is no longer seen on the stack. Note that the nmethod | |
745 // might be "entrant" and not on the stack and so could be zombied immediately | |
746 // but we can't tell because we don't track it on stack until it becomes | |
747 // non-entrant. | |
748 | |
749 if (nm->is_not_entrant() && nm->can_not_entrant_be_converted()) { | |
750 nm->make_zombie(); | |
751 } else { | |
752 nm->make_not_entrant(); | |
753 } | |
754 } | |
755 } | |
756 } | |
757 | |
758 void CodeCache::make_marked_nmethods_not_entrant() { | |
759 assert_locked_or_safepoint(CodeCache_lock); | |
760 FOR_ALL_ALIVE_NMETHODS(nm) { | |
761 if (nm->is_marked_for_deoptimization()) { | |
762 nm->make_not_entrant(); | |
763 } | |
764 } | |
765 } | |
766 | |
767 void CodeCache::verify() { | |
768 _heap->verify(); | |
769 FOR_ALL_ALIVE_BLOBS(p) { | |
770 p->verify(); | |
771 } | |
772 } | |
773 | |
10405 | 774 void CodeCache::report_codemem_full() { |
775 _codemem_full_count++; | |
776 EventCodeCacheFull event; | |
777 if (event.should_commit()) { | |
778 event.set_startAddress((u8)low_bound()); | |
779 event.set_commitedTopAddress((u8)high()); | |
780 event.set_reservedTopAddress((u8)high_bound()); | |
781 event.set_entryCount(nof_blobs()); | |
782 event.set_methodCount(nof_nmethods()); | |
783 event.set_adaptorCount(nof_adapters()); | |
784 event.set_unallocatedCapacity(unallocated_capacity()/K); | |
785 event.set_fullCount(_codemem_full_count); | |
786 event.commit(); | |
787 } | |
788 } | |
789 | |
0 | 790 //------------------------------------------------------------------------------------------------ |
791 // Non-product version | |
792 | |
793 #ifndef PRODUCT | |
794 | |
795 void CodeCache::verify_if_often() { | |
796 if (VerifyCodeCacheOften) { | |
797 _heap->verify(); | |
798 } | |
799 } | |
800 | |
989 | 801 void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { |
802 if (PrintCodeCache2) { // Need to add a new flag | |
803 ResourceMark rm; | |
804 if (size == 0) size = cb->size(); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
805 tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, p2i(cb), size); |
989 | 806 } |
807 } | |
808 | |
0 | 809 void CodeCache::print_internals() { |
810 int nmethodCount = 0; | |
811 int runtimeStubCount = 0; | |
812 int adapterCount = 0; | |
813 int deoptimizationStubCount = 0; | |
814 int uncommonTrapStubCount = 0; | |
815 int bufferBlobCount = 0; | |
816 int total = 0; | |
817 int nmethodAlive = 0; | |
818 int nmethodNotEntrant = 0; | |
819 int nmethodZombie = 0; | |
820 int nmethodUnloaded = 0; | |
821 int nmethodJava = 0; | |
822 int nmethodNative = 0; | |
823 int maxCodeSize = 0; | |
824 ResourceMark rm; | |
825 | |
826 CodeBlob *cb; | |
827 for (cb = first(); cb != NULL; cb = next(cb)) { | |
828 total++; | |
829 if (cb->is_nmethod()) { | |
830 nmethod* nm = (nmethod*)cb; | |
831 | |
832 if (Verbose && nm->method() != NULL) { | |
833 ResourceMark rm; | |
834 char *method_name = nm->method()->name_and_sig_as_C_string(); | |
835 tty->print("%s", method_name); | |
836 if(nm->is_alive()) { tty->print_cr(" alive"); } | |
837 if(nm->is_not_entrant()) { tty->print_cr(" not-entrant"); } | |
838 if(nm->is_zombie()) { tty->print_cr(" zombie"); } | |
839 } | |
840 | |
841 nmethodCount++; | |
842 | |
843 if(nm->is_alive()) { nmethodAlive++; } | |
844 if(nm->is_not_entrant()) { nmethodNotEntrant++; } | |
845 if(nm->is_zombie()) { nmethodZombie++; } | |
846 if(nm->is_unloaded()) { nmethodUnloaded++; } | |
847 if(nm->is_native_method()) { nmethodNative++; } | |
848 | |
849 if(nm->method() != NULL && nm->is_java_method()) { | |
850 nmethodJava++; | |
1748 | 851 if (nm->insts_size() > maxCodeSize) { |
852 maxCodeSize = nm->insts_size(); | |
0 | 853 } |
854 } | |
855 } else if (cb->is_runtime_stub()) { | |
856 runtimeStubCount++; | |
857 } else if (cb->is_deoptimization_stub()) { | |
858 deoptimizationStubCount++; | |
859 } else if (cb->is_uncommon_trap_stub()) { | |
860 uncommonTrapStubCount++; | |
861 } else if (cb->is_adapter_blob()) { | |
862 adapterCount++; | |
863 } else if (cb->is_buffer_blob()) { | |
864 bufferBlobCount++; | |
865 } | |
866 } | |
867 | |
868 int bucketSize = 512; | |
869 int bucketLimit = maxCodeSize / bucketSize + 1; | |
6197 | 870 int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode); |
0 | 871 memset(buckets,0,sizeof(int) * bucketLimit); |
872 | |
873 for (cb = first(); cb != NULL; cb = next(cb)) { | |
874 if (cb->is_nmethod()) { | |
875 nmethod* nm = (nmethod*)cb; | |
876 if(nm->is_java_method()) { | |
1748 | 877 buckets[nm->insts_size() / bucketSize]++; |
0 | 878 } |
879 } | |
880 } | |
881 tty->print_cr("Code Cache Entries (total of %d)",total); | |
882 tty->print_cr("-------------------------------------------------"); | |
883 tty->print_cr("nmethods: %d",nmethodCount); | |
884 tty->print_cr("\talive: %d",nmethodAlive); | |
885 tty->print_cr("\tnot_entrant: %d",nmethodNotEntrant); | |
886 tty->print_cr("\tzombie: %d",nmethodZombie); | |
887 tty->print_cr("\tunloaded: %d",nmethodUnloaded); | |
888 tty->print_cr("\tjava: %d",nmethodJava); | |
889 tty->print_cr("\tnative: %d",nmethodNative); | |
890 tty->print_cr("runtime_stubs: %d",runtimeStubCount); | |
891 tty->print_cr("adapters: %d",adapterCount); | |
892 tty->print_cr("buffer blobs: %d",bufferBlobCount); | |
893 tty->print_cr("deoptimization_stubs: %d",deoptimizationStubCount); | |
894 tty->print_cr("uncommon_traps: %d",uncommonTrapStubCount); | |
895 tty->print_cr("\nnmethod size distribution (non-zombie java)"); | |
896 tty->print_cr("-------------------------------------------------"); | |
897 | |
898 for(int i=0; i<bucketLimit; i++) { | |
899 if(buckets[i] != 0) { | |
900 tty->print("%d - %d bytes",i*bucketSize,(i+1)*bucketSize); | |
901 tty->fill_to(40); | |
902 tty->print_cr("%d",buckets[i]); | |
903 } | |
904 } | |
905 | |
6197 | 906 FREE_C_HEAP_ARRAY(int, buckets, mtCode); |
0 | 907 } |
908 | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
909 #endif // !PRODUCT |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
910 |
0 | 911 void CodeCache::print() { |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
912 print_summary(tty); |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
913 |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
914 #ifndef PRODUCT |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
915 if (!Verbose) return; |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
916 |
0 | 917 CodeBlob_sizes live; |
918 CodeBlob_sizes dead; | |
919 | |
920 FOR_ALL_BLOBS(p) { | |
921 if (!p->is_alive()) { | |
922 dead.add(p); | |
923 } else { | |
924 live.add(p); | |
925 } | |
926 } | |
927 | |
928 tty->print_cr("CodeCache:"); | |
929 | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
930 tty->print_cr("nmethod dependency checking time %f, per dependent %f", dependentCheckTime.seconds(), |
0 | 931 dependentCheckTime.seconds() / dependentCheckCount); |
932 | |
933 if (!live.is_empty()) { | |
934 live.print("live"); | |
935 } | |
936 if (!dead.is_empty()) { | |
937 dead.print("dead"); | |
938 } | |
939 | |
940 | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
941 if (WizardMode) { |
0 | 942 // print the oop_map usage |
943 int code_size = 0; | |
944 int number_of_blobs = 0; | |
945 int number_of_oop_maps = 0; | |
946 int map_size = 0; | |
947 FOR_ALL_BLOBS(p) { | |
948 if (p->is_alive()) { | |
949 number_of_blobs++; | |
1748 | 950 code_size += p->code_size(); |
0 | 951 OopMapSet* set = p->oop_maps(); |
952 if (set != NULL) { | |
953 number_of_oop_maps += set->size(); | |
1748 | 954 map_size += set->heap_size(); |
0 | 955 } |
956 } | |
957 } | |
958 tty->print_cr("OopMaps"); | |
959 tty->print_cr(" #blobs = %d", number_of_blobs); | |
960 tty->print_cr(" code size = %d", code_size); | |
961 tty->print_cr(" #oop_maps = %d", number_of_oop_maps); | |
962 tty->print_cr(" map size = %d", map_size); | |
963 } | |
964 | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
965 #endif // !PRODUCT |
0 | 966 } |
967 | |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
968 void CodeCache::print_summary(outputStream* st, bool detailed) { |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
969 size_t total = (_heap->high_boundary() - _heap->low_boundary()); |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
970 st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
971 "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb", |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
972 total/K, (total - unallocated_capacity())/K, |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
973 maxCodeCacheUsed/K, unallocated_capacity()/K); |
1907 | 974 |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
975 if (detailed) { |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
976 st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
977 p2i(_heap->low_boundary()), |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
978 p2i(_heap->high()), |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12324
diff
changeset
|
979 p2i(_heap->high_boundary())); |
7595
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
980 st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
981 " adapters=" UINT32_FORMAT, |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
982 nof_blobs(), nof_nmethods(), nof_adapters()); |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
983 st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ? |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
984 "enabled" : Arguments::mode() == Arguments::_int ? |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
985 "disabled (interpreter mode)" : |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
986 "disabled (not enough contiguous free space left)"); |
9deda4d8e126
8005204: Code Cache Reduction: command line options implementation
vladidan
parents:
6787
diff
changeset
|
987 } |
1907 | 988 } |
2353
1c0cf339481b
7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
kvn
parents:
2091
diff
changeset
|
989 |
1c0cf339481b
7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
kvn
parents:
2091
diff
changeset
|
990 void CodeCache::log_state(outputStream* st) { |
1c0cf339481b
7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
kvn
parents:
2091
diff
changeset
|
991 st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
992 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
2353
1c0cf339481b
7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
kvn
parents:
2091
diff
changeset
|
993 nof_blobs(), nof_nmethods(), nof_adapters(), |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
7595
diff
changeset
|
994 unallocated_capacity()); |
2353
1c0cf339481b
7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
kvn
parents:
2091
diff
changeset
|
995 } |
2457
527977d4f740
7033779: CodeCache::largest_free_block may need to hold the CodeCache lock
never
parents:
2376
diff
changeset
|
996 |