Mercurial > hg > truffle
annotate src/share/vm/code/nmethod.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 | 2c6ef90f030a |
children | b12a2a9b05ca |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17915
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/codeCache.hpp" | |
27 #include "code/compiledIC.hpp" | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3784
diff
changeset
|
28 #include "code/dependencies.hpp" |
1972 | 29 #include "code/nmethod.hpp" |
30 #include "code/scopeDesc.hpp" | |
31 #include "compiler/abstractCompiler.hpp" | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
32 #include "compiler/compileBroker.hpp" |
1972 | 33 #include "compiler/compileLog.hpp" |
34 #include "compiler/compilerOracle.hpp" | |
35 #include "compiler/disassembler.hpp" | |
36 #include "interpreter/bytecode.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
37 #include "oops/methodData.hpp" |
1972 | 38 #include "prims/jvmtiRedefineClassesTrace.hpp" |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
39 #include "prims/jvmtiImpl.hpp" |
20197
ce8f6bb717c9
8042195: Introduce umbrella header orderAccess.inline.hpp.
goetz
parents:
20191
diff
changeset
|
40 #include "runtime/orderAccess.inline.hpp" |
1972 | 41 #include "runtime/sharedRuntime.hpp" |
42 #include "runtime/sweeper.hpp" | |
43 #include "utilities/dtrace.hpp" | |
44 #include "utilities/events.hpp" | |
45 #include "utilities/xmlstream.hpp" | |
46 #ifdef SHARK | |
47 #include "shark/sharkCompiler.hpp" | |
48 #endif | |
0 | 49 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17915
diff
changeset
|
50 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17915
diff
changeset
|
51 |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
52 unsigned char nmethod::_global_unloading_clock = 0; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
53 |
0 | 54 #ifdef DTRACE_ENABLED |
55 | |
56 // Only bother with this argument setup if dtrace is available | |
57 | |
4006 | 58 #ifndef USDT2 |
0 | 59 HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load, |
60 const char*, int, const char*, int, const char*, int, void*, size_t); | |
61 | |
62 HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload, | |
63 char*, int, char*, int, char*, int); | |
64 | |
65 #define DTRACE_METHOD_UNLOAD_PROBE(method) \ | |
66 { \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
67 Method* m = (method); \ |
0 | 68 if (m != NULL) { \ |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
69 Symbol* klass_name = m->klass_name(); \ |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
70 Symbol* name = m->name(); \ |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
71 Symbol* signature = m->signature(); \ |
0 | 72 HS_DTRACE_PROBE6(hotspot, compiled__method__unload, \ |
73 klass_name->bytes(), klass_name->utf8_length(), \ | |
74 name->bytes(), name->utf8_length(), \ | |
75 signature->bytes(), signature->utf8_length()); \ | |
76 } \ | |
77 } | |
4006 | 78 #else /* USDT2 */ |
79 #define DTRACE_METHOD_UNLOAD_PROBE(method) \ | |
80 { \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
81 Method* m = (method); \ |
4006 | 82 if (m != NULL) { \ |
83 Symbol* klass_name = m->klass_name(); \ | |
84 Symbol* name = m->name(); \ | |
85 Symbol* signature = m->signature(); \ | |
86 HOTSPOT_COMPILED_METHOD_UNLOAD( \ | |
87 (char *) klass_name->bytes(), klass_name->utf8_length(), \ | |
88 (char *) name->bytes(), name->utf8_length(), \ | |
89 (char *) signature->bytes(), signature->utf8_length()); \ | |
90 } \ | |
91 } | |
92 #endif /* USDT2 */ | |
0 | 93 |
94 #else // ndef DTRACE_ENABLED | |
95 | |
96 #define DTRACE_METHOD_UNLOAD_PROBE(method) | |
97 | |
98 #endif | |
99 | |
100 bool nmethod::is_compiled_by_c1() const { | |
12161
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
101 if (compiler() == NULL) { |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
102 return false; |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
103 } |
0 | 104 return compiler()->is_c1(); |
105 } | |
106 bool nmethod::is_compiled_by_c2() const { | |
12161
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
107 if (compiler() == NULL) { |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
108 return false; |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
109 } |
0 | 110 return compiler()->is_c2(); |
111 } | |
1692 | 112 bool nmethod::is_compiled_by_shark() const { |
12161
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
113 if (compiler() == NULL) { |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
114 return false; |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
115 } |
1692 | 116 return compiler()->is_shark(); |
117 } | |
0 | 118 |
119 | |
120 | |
121 //--------------------------------------------------------------------------------- | |
122 // NMethod statistics | |
123 // They are printed under various flags, including: | |
124 // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation. | |
125 // (In the latter two cases, they like other stats are printed to the log only.) | |
126 | |
127 #ifndef PRODUCT | |
128 // These variables are put into one block to reduce relocations | |
129 // and make it simpler to print from the debugger. | |
130 static | |
131 struct nmethod_stats_struct { | |
132 int nmethod_count; | |
133 int total_size; | |
134 int relocation_size; | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
135 int consts_size; |
1748 | 136 int insts_size; |
0 | 137 int stub_size; |
138 int scopes_data_size; | |
139 int scopes_pcs_size; | |
140 int dependencies_size; | |
141 int handler_table_size; | |
142 int nul_chk_table_size; | |
143 int oops_size; | |
144 | |
145 void note_nmethod(nmethod* nm) { | |
146 nmethod_count += 1; | |
147 total_size += nm->size(); | |
148 relocation_size += nm->relocation_size(); | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
149 consts_size += nm->consts_size(); |
1748 | 150 insts_size += nm->insts_size(); |
0 | 151 stub_size += nm->stub_size(); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
152 oops_size += nm->oops_size(); |
0 | 153 scopes_data_size += nm->scopes_data_size(); |
154 scopes_pcs_size += nm->scopes_pcs_size(); | |
155 dependencies_size += nm->dependencies_size(); | |
156 handler_table_size += nm->handler_table_size(); | |
157 nul_chk_table_size += nm->nul_chk_table_size(); | |
158 } | |
159 void print_nmethod_stats() { | |
160 if (nmethod_count == 0) return; | |
161 tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count); | |
162 if (total_size != 0) tty->print_cr(" total in heap = %d", total_size); | |
163 if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size); | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
164 if (consts_size != 0) tty->print_cr(" constants = %d", consts_size); |
1748 | 165 if (insts_size != 0) tty->print_cr(" main code = %d", insts_size); |
0 | 166 if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
167 if (oops_size != 0) tty->print_cr(" oops = %d", oops_size); |
0 | 168 if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size); |
169 if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size); | |
170 if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size); | |
171 if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size); | |
172 if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size); | |
173 } | |
174 | |
175 int native_nmethod_count; | |
176 int native_total_size; | |
177 int native_relocation_size; | |
1748 | 178 int native_insts_size; |
0 | 179 int native_oops_size; |
180 void note_native_nmethod(nmethod* nm) { | |
181 native_nmethod_count += 1; | |
182 native_total_size += nm->size(); | |
183 native_relocation_size += nm->relocation_size(); | |
1748 | 184 native_insts_size += nm->insts_size(); |
0 | 185 native_oops_size += nm->oops_size(); |
186 } | |
187 void print_native_nmethod_stats() { | |
188 if (native_nmethod_count == 0) return; | |
189 tty->print_cr("Statistics for %d native nmethods:", native_nmethod_count); | |
190 if (native_total_size != 0) tty->print_cr(" N. total size = %d", native_total_size); | |
191 if (native_relocation_size != 0) tty->print_cr(" N. relocation = %d", native_relocation_size); | |
1748 | 192 if (native_insts_size != 0) tty->print_cr(" N. main code = %d", native_insts_size); |
0 | 193 if (native_oops_size != 0) tty->print_cr(" N. oops = %d", native_oops_size); |
194 } | |
195 | |
196 int pc_desc_resets; // number of resets (= number of caches) | |
197 int pc_desc_queries; // queries to nmethod::find_pc_desc | |
198 int pc_desc_approx; // number of those which have approximate true | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
199 int pc_desc_repeats; // number of _pc_descs[0] hits |
0 | 200 int pc_desc_hits; // number of LRU cache hits |
201 int pc_desc_tests; // total number of PcDesc examinations | |
202 int pc_desc_searches; // total number of quasi-binary search steps | |
203 int pc_desc_adds; // number of LUR cache insertions | |
204 | |
205 void print_pc_stats() { | |
206 tty->print_cr("PcDesc Statistics: %d queries, %.2f comparisons per query", | |
207 pc_desc_queries, | |
208 (double)(pc_desc_tests + pc_desc_searches) | |
209 / pc_desc_queries); | |
210 tty->print_cr(" caches=%d queries=%d/%d, hits=%d+%d, tests=%d+%d, adds=%d", | |
211 pc_desc_resets, | |
212 pc_desc_queries, pc_desc_approx, | |
213 pc_desc_repeats, pc_desc_hits, | |
214 pc_desc_tests, pc_desc_searches, pc_desc_adds); | |
215 } | |
216 } nmethod_stats; | |
217 #endif //PRODUCT | |
218 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2195
diff
changeset
|
219 |
0 | 220 //--------------------------------------------------------------------------------- |
221 | |
222 | |
223 ExceptionCache::ExceptionCache(Handle exception, address pc, address handler) { | |
224 assert(pc != NULL, "Must be non null"); | |
225 assert(exception.not_null(), "Must be non null"); | |
226 assert(handler != NULL, "Must be non null"); | |
227 | |
228 _count = 0; | |
229 _exception_type = exception->klass(); | |
230 _next = NULL; | |
231 | |
232 add_address_and_handler(pc,handler); | |
233 } | |
234 | |
235 | |
236 address ExceptionCache::match(Handle exception, address pc) { | |
237 assert(pc != NULL,"Must be non null"); | |
238 assert(exception.not_null(),"Must be non null"); | |
239 if (exception->klass() == exception_type()) { | |
240 return (test_address(pc)); | |
241 } | |
242 | |
243 return NULL; | |
244 } | |
245 | |
246 | |
247 bool ExceptionCache::match_exception_with_space(Handle exception) { | |
248 assert(exception.not_null(),"Must be non null"); | |
249 if (exception->klass() == exception_type() && count() < cache_size) { | |
250 return true; | |
251 } | |
252 return false; | |
253 } | |
254 | |
255 | |
256 address ExceptionCache::test_address(address addr) { | |
257 for (int i=0; i<count(); i++) { | |
258 if (pc_at(i) == addr) { | |
259 return handler_at(i); | |
260 } | |
261 } | |
262 return NULL; | |
263 } | |
264 | |
265 | |
266 bool ExceptionCache::add_address_and_handler(address addr, address handler) { | |
267 if (test_address(addr) == handler) return true; | |
268 if (count() < cache_size) { | |
269 set_pc_at(count(),addr); | |
270 set_handler_at(count(), handler); | |
271 increment_count(); | |
272 return true; | |
273 } | |
274 return false; | |
275 } | |
276 | |
277 | |
278 // private method for handling exception cache | |
279 // These methods are private, and used to manipulate the exception cache | |
280 // directly. | |
281 ExceptionCache* nmethod::exception_cache_entry_for_exception(Handle exception) { | |
282 ExceptionCache* ec = exception_cache(); | |
283 while (ec != NULL) { | |
284 if (ec->match_exception_with_space(exception)) { | |
285 return ec; | |
286 } | |
287 ec = ec->next(); | |
288 } | |
289 return NULL; | |
290 } | |
291 | |
292 | |
293 //----------------------------------------------------------------------------- | |
294 | |
295 | |
296 // Helper used by both find_pc_desc methods. | |
297 static inline bool match_desc(PcDesc* pc, int pc_offset, bool approximate) { | |
298 NOT_PRODUCT(++nmethod_stats.pc_desc_tests); | |
299 if (!approximate) | |
300 return pc->pc_offset() == pc_offset; | |
301 else | |
302 return (pc-1)->pc_offset() < pc_offset && pc_offset <= pc->pc_offset(); | |
303 } | |
304 | |
305 void PcDescCache::reset_to(PcDesc* initial_pc_desc) { | |
306 if (initial_pc_desc == NULL) { | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
307 _pc_descs[0] = NULL; // native method; no PcDescs at all |
0 | 308 return; |
309 } | |
310 NOT_PRODUCT(++nmethod_stats.pc_desc_resets); | |
311 // reset the cache by filling it with benign (non-null) values | |
312 assert(initial_pc_desc->pc_offset() < 0, "must be sentinel"); | |
313 for (int i = 0; i < cache_size; i++) | |
314 _pc_descs[i] = initial_pc_desc; | |
315 } | |
316 | |
317 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) { | |
318 NOT_PRODUCT(++nmethod_stats.pc_desc_queries); | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
319 NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx); |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
320 |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
321 // Note: one might think that caching the most recently |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
322 // read value separately would be a win, but one would be |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
323 // wrong. When many threads are updating it, the cache |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
324 // line it's in would bounce between caches, negating |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
325 // any benefit. |
0 | 326 |
327 // In order to prevent race conditions do not load cache elements | |
328 // repeatedly, but use a local copy: | |
329 PcDesc* res; | |
330 | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
331 // Step one: Check the most recently added value. |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
332 res = _pc_descs[0]; |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
333 if (res == NULL) return NULL; // native method; no PcDescs at all |
0 | 334 if (match_desc(res, pc_offset, approximate)) { |
335 NOT_PRODUCT(++nmethod_stats.pc_desc_repeats); | |
336 return res; | |
337 } | |
338 | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
339 // Step two: Check the rest of the LRU cache. |
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
340 for (int i = 1; i < cache_size; ++i) { |
0 | 341 res = _pc_descs[i]; |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
342 if (res->pc_offset() < 0) break; // optimization: skip empty cache |
0 | 343 if (match_desc(res, pc_offset, approximate)) { |
344 NOT_PRODUCT(++nmethod_stats.pc_desc_hits); | |
345 return res; | |
346 } | |
347 } | |
348 | |
349 // Report failure. | |
350 return NULL; | |
351 } | |
352 | |
353 void PcDescCache::add_pc_desc(PcDesc* pc_desc) { | |
354 NOT_PRODUCT(++nmethod_stats.pc_desc_adds); | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
355 // Update the LRU cache by shifting pc_desc forward. |
0 | 356 for (int i = 0; i < cache_size; i++) { |
357 PcDesc* next = _pc_descs[i]; | |
358 _pc_descs[i] = pc_desc; | |
359 pc_desc = next; | |
360 } | |
361 } | |
362 | |
363 // adjust pcs_size so that it is a multiple of both oopSize and | |
364 // sizeof(PcDesc) (assumes that if sizeof(PcDesc) is not a multiple | |
365 // of oopSize, then 2*sizeof(PcDesc) is) | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
366 static int adjust_pcs_size(int pcs_size) { |
0 | 367 int nsize = round_to(pcs_size, oopSize); |
368 if ((nsize % sizeof(PcDesc)) != 0) { | |
369 nsize = pcs_size + sizeof(PcDesc); | |
370 } | |
2339
3d5a546351ef
7023931: PcDescCache::find_pc_desc should not write _last_pc_desc
phh
parents:
2321
diff
changeset
|
371 assert((nsize % oopSize) == 0, "correct alignment"); |
0 | 372 return nsize; |
373 } | |
374 | |
375 //----------------------------------------------------------------------------- | |
376 | |
377 | |
378 void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) { | |
379 assert(ExceptionCache_lock->owned_by_self(),"Must hold the ExceptionCache_lock"); | |
380 assert(new_entry != NULL,"Must be non null"); | |
381 assert(new_entry->next() == NULL, "Must be null"); | |
382 | |
383 if (exception_cache() != NULL) { | |
384 new_entry->set_next(exception_cache()); | |
385 } | |
386 set_exception_cache(new_entry); | |
387 } | |
388 | |
20269 | 389 void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) { |
0 | 390 ExceptionCache* prev = NULL; |
391 ExceptionCache* curr = exception_cache(); | |
20269 | 392 |
393 while (curr != NULL) { | |
394 ExceptionCache* next = curr->next(); | |
395 | |
396 Klass* ex_klass = curr->exception_type(); | |
397 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { | |
398 if (prev == NULL) { | |
399 set_exception_cache(next); | |
400 } else { | |
401 prev->set_next(next); | |
402 } | |
403 delete curr; | |
404 // prev stays the same. | |
405 } else { | |
406 prev = curr; | |
407 } | |
408 | |
409 curr = next; | |
0 | 410 } |
411 } | |
412 | |
413 // public method for accessing the exception cache | |
414 // These are the public access methods. | |
415 address nmethod::handler_for_exception_and_pc(Handle exception, address pc) { | |
416 // We never grab a lock to read the exception cache, so we may | |
417 // have false negatives. This is okay, as it can only happen during | |
418 // the first few exception lookups for a given nmethod. | |
419 ExceptionCache* ec = exception_cache(); | |
420 while (ec != NULL) { | |
421 address ret_val; | |
422 if ((ret_val = ec->match(exception,pc)) != NULL) { | |
423 return ret_val; | |
424 } | |
425 ec = ec->next(); | |
426 } | |
427 return NULL; | |
428 } | |
429 | |
430 | |
431 void nmethod::add_handler_for_exception_and_pc(Handle exception, address pc, address handler) { | |
432 // There are potential race conditions during exception cache updates, so we | |
433 // must own the ExceptionCache_lock before doing ANY modifications. Because | |
605 | 434 // we don't lock during reads, it is possible to have several threads attempt |
0 | 435 // to update the cache with the same data. We need to check for already inserted |
436 // copies of the current data before adding it. | |
437 | |
438 MutexLocker ml(ExceptionCache_lock); | |
439 ExceptionCache* target_entry = exception_cache_entry_for_exception(exception); | |
440 | |
441 if (target_entry == NULL || !target_entry->add_address_and_handler(pc,handler)) { | |
442 target_entry = new ExceptionCache(exception,pc,handler); | |
443 add_exception_cache_entry(target_entry); | |
444 } | |
445 } | |
446 | |
447 | |
448 //-------------end of code for ExceptionCache-------------- | |
449 | |
450 | |
451 int nmethod::total_size() const { | |
452 return | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
453 consts_size() + |
1748 | 454 insts_size() + |
0 | 455 stub_size() + |
456 scopes_data_size() + | |
457 scopes_pcs_size() + | |
458 handler_table_size() + | |
459 nul_chk_table_size(); | |
460 } | |
461 | |
462 const char* nmethod::compile_kind() const { | |
463 if (is_osr_method()) return "osr"; | |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
464 if (method() != NULL && is_native_method()) return "c2n"; |
0 | 465 return NULL; |
466 } | |
467 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
468 // Fill in default values for various flag fields |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
469 void nmethod::init_defaults() { |
13441 | 470 _state = in_use; |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
471 _unloading_clock = 0; |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
472 _marked_for_reclamation = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
473 _has_flushed_dependencies = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
474 _has_unsafe_access = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
475 _has_method_handle_invokes = 0; |
4873
0382d2b469b2
7013347: allow crypto functions to be called inline to enhance performance
never
parents:
4872
diff
changeset
|
476 _lazy_critical_native = 0; |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6790
diff
changeset
|
477 _has_wide_vectors = 0; |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
478 _marked_for_deoptimization = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
479 _lock_count = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
480 _stack_traversal_mark = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
481 _unload_reported = false; // jvmti state |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
482 |
1726 | 483 #ifdef ASSERT |
484 _oops_are_stale = false; | |
485 #endif | |
486 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
487 _oops_do_mark_link = NULL; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
488 _jmethod_id = NULL; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
489 _osr_link = NULL; |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
490 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
491 _unloading_next = NULL; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
492 } else { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
493 _scavenge_root_link = NULL; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
494 } |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
495 _scavenge_root_state = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
496 _compiler = NULL; |
17780 | 497 #if INCLUDE_RTM_OPT |
498 _rtm_state = NoRTM; | |
499 #endif | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
500 #ifdef HAVE_DTRACE_H |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
501 _trap_offset = 0; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
502 #endif // def HAVE_DTRACE_H |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
503 } |
0 | 504 |
505 nmethod* nmethod::new_native_nmethod(methodHandle method, | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
506 int compile_id, |
0 | 507 CodeBuffer *code_buffer, |
508 int vep_offset, | |
509 int frame_complete, | |
510 int frame_size, | |
511 ByteSize basic_lock_owner_sp_offset, | |
512 ByteSize basic_lock_sp_offset, | |
513 OopMapSet* oop_maps) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
514 code_buffer->finalize_oop_references(method); |
0 | 515 // create nmethod |
516 nmethod* nm = NULL; | |
517 { | |
518 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
519 int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); | |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
520 CodeOffsets offsets; |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
521 offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
522 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
523 nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
524 compile_id, &offsets, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
525 code_buffer, frame_size, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
526 basic_lock_owner_sp_offset, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
527 basic_lock_sp_offset, oop_maps); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
528 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm)); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
529 if (PrintAssembly && nm != NULL) { |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
530 Disassembler::decode(nm); |
8864
3c786355ffb4
8009026: [parfait] Null pointer deference in hotspot/src/share/vm/code/nmethod.cpp
morris
parents:
6983
diff
changeset
|
531 } |
0 | 532 } |
533 // verify nmethod | |
534 debug_only(if (nm) nm->verify();) // might block | |
535 | |
536 if (nm != NULL) { | |
537 nm->log_new_nmethod(); | |
538 } | |
539 | |
540 return nm; | |
541 } | |
542 | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
543 #ifdef HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
544 nmethod* nmethod::new_dtrace_nmethod(methodHandle method, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
545 CodeBuffer *code_buffer, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
546 int vep_offset, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
547 int trap_offset, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
548 int frame_complete, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
549 int frame_size) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
550 code_buffer->finalize_oop_references(method); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
551 // create nmethod |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
552 nmethod* nm = NULL; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
553 { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
554 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
555 int nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
556 CodeOffsets offsets; |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
557 offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
558 offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
559 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
560 |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
561 nm = new (nmethod_size) nmethod(method(), nmethod_size, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
562 &offsets, code_buffer, frame_size); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
563 |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
564 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm)); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
565 if (PrintAssembly && nm != NULL) { |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
566 Disassembler::decode(nm); |
8864
3c786355ffb4
8009026: [parfait] Null pointer deference in hotspot/src/share/vm/code/nmethod.cpp
morris
parents:
6983
diff
changeset
|
567 } |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
568 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
569 // verify nmethod |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
570 debug_only(if (nm) nm->verify();) // might block |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
571 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
572 if (nm != NULL) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
573 nm->log_new_nmethod(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
574 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
575 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
576 return nm; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
577 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
578 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
579 #endif // def HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
580 |
0 | 581 nmethod* nmethod::new_nmethod(methodHandle method, |
582 int compile_id, | |
583 int entry_bci, | |
584 CodeOffsets* offsets, | |
585 int orig_pc_offset, | |
586 DebugInformationRecorder* debug_info, | |
587 Dependencies* dependencies, | |
588 CodeBuffer* code_buffer, int frame_size, | |
589 OopMapSet* oop_maps, | |
590 ExceptionHandlerTable* handler_table, | |
591 ImplicitExceptionTable* nul_chk_table, | |
592 AbstractCompiler* compiler, | |
593 int comp_level | |
594 ) | |
595 { | |
596 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
597 code_buffer->finalize_oop_references(method); |
0 | 598 // create nmethod |
599 nmethod* nm = NULL; | |
600 { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
601 int nmethod_size = | |
602 allocation_size(code_buffer, sizeof(nmethod)) | |
603 + adjust_pcs_size(debug_info->pcs_size()) | |
604 + round_to(dependencies->size_in_bytes() , oopSize) | |
605 + round_to(handler_table->size_in_bytes(), oopSize) | |
606 + round_to(nul_chk_table->size_in_bytes(), oopSize) | |
607 + round_to(debug_info->data_size() , oopSize); | |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
608 |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
609 nm = new (nmethod_size) |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
610 nmethod(method(), nmethod_size, compile_id, entry_bci, offsets, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
611 orig_pc_offset, debug_info, dependencies, code_buffer, frame_size, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
612 oop_maps, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
613 handler_table, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
614 nul_chk_table, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
615 compiler, |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
616 comp_level); |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
617 |
0 | 618 if (nm != NULL) { |
619 // To make dependency checking during class loading fast, record | |
620 // the nmethod dependencies in the classes it is dependent on. | |
621 // This allows the dependency checking code to simply walk the | |
622 // class hierarchy above the loaded class, checking only nmethods | |
623 // which are dependent on those classes. The slow way is to | |
624 // check every nmethod for dependencies which makes it linear in | |
625 // the number of methods compiled. For applications with a lot | |
626 // classes the slow way is too slow. | |
627 for (Dependencies::DepStream deps(nm); deps.next(); ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
628 Klass* klass = deps.context_type(); |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
629 if (klass == NULL) { |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
630 continue; // ignore things like evol_method |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
631 } |
0 | 632 |
633 // record this nmethod as dependent on this klass | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
634 InstanceKlass::cast(klass)->add_dependent_nmethod(nm); |
0 | 635 } |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
636 NOT_PRODUCT(nmethod_stats.note_nmethod(nm)); |
14438
4cdf4f71177d
8029025: PPC64 (part 203): opto: Move static _in_dump_cnt to Compile object.
goetz
parents:
14435
diff
changeset
|
637 if (PrintAssembly || CompilerOracle::has_option_string(method, "PrintAssembly")) { |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
638 Disassembler::decode(nm); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
639 } |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
640 } |
0 | 641 } |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
642 // Do verification and logging outside CodeCache_lock. |
0 | 643 if (nm != NULL) { |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
644 // Safepoints in nmethod::verify aren't allowed because nm hasn't been installed yet. |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
645 DEBUG_ONLY(nm->verify();) |
0 | 646 nm->log_new_nmethod(); |
647 } | |
648 return nm; | |
649 } | |
650 | |
651 | |
652 // For native wrappers | |
653 nmethod::nmethod( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
654 Method* method, |
0 | 655 int nmethod_size, |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
656 int compile_id, |
0 | 657 CodeOffsets* offsets, |
658 CodeBuffer* code_buffer, | |
659 int frame_size, | |
660 ByteSize basic_lock_owner_sp_offset, | |
661 ByteSize basic_lock_sp_offset, | |
662 OopMapSet* oop_maps ) | |
663 : CodeBlob("native nmethod", code_buffer, sizeof(nmethod), | |
664 nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), | |
2019 | 665 _native_receiver_sp_offset(basic_lock_owner_sp_offset), |
666 _native_basic_lock_sp_offset(basic_lock_sp_offset) | |
0 | 667 { |
668 { | |
669 debug_only(No_Safepoint_Verifier nsv;) | |
670 assert_locked_or_safepoint(CodeCache_lock); | |
671 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
672 init_defaults(); |
0 | 673 _method = method; |
674 _entry_bci = InvocationEntryBci; | |
675 // We have no exception handler or deopt handler make the | |
676 // values something that will never match a pc like the nmethod vtable entry | |
677 _exception_offset = 0; | |
678 _deoptimize_offset = 0; | |
1204 | 679 _deoptimize_mh_offset = 0; |
0 | 680 _orig_pc_offset = 0; |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
681 |
1748 | 682 _consts_offset = data_offset(); |
0 | 683 _stub_offset = data_offset(); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
684 _oops_offset = data_offset(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
685 _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
686 _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); |
0 | 687 _scopes_pcs_offset = _scopes_data_offset; |
688 _dependencies_offset = _scopes_pcs_offset; | |
689 _handler_table_offset = _dependencies_offset; | |
690 _nul_chk_table_offset = _handler_table_offset; | |
691 _nmethod_end_offset = _nul_chk_table_offset; | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
692 _compile_id = compile_id; |
0 | 693 _comp_level = CompLevel_none; |
1748 | 694 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
695 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); | |
0 | 696 _osr_entry_point = NULL; |
697 _exception_cache = NULL; | |
698 _pc_desc_cache.reset_to(NULL); | |
12324
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
699 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
0 | 700 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
701 code_buffer->copy_values_to(this); |
20191
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
702 if (ScavengeRootsInCode) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
703 if (detect_scavenge_root_oops()) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
704 CodeCache::add_scavenge_root_nmethod(this); |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
705 } |
12080 | 706 Universe::heap()->register_nmethod(this); |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2375
diff
changeset
|
707 } |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
708 debug_only(verify_scavenge_root_oops()); |
0 | 709 CodeCache::commit(this); |
710 } | |
711 | |
712 if (PrintNativeNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { | |
713 ttyLocker ttyl; // keep the following output all in one block | |
714 // This output goes directly to the tty, not the compiler log. | |
715 // To enable tools to match it up with the compilation activity, | |
716 // be sure to tag this tty output with the compile ID. | |
717 if (xtty != NULL) { | |
718 xtty->begin_head("print_native_nmethod"); | |
719 xtty->method(_method); | |
720 xtty->stamp(); | |
721 xtty->end_head(" address='" INTPTR_FORMAT "'", (intptr_t) this); | |
722 } | |
723 // print the header part first | |
724 print(); | |
725 // then print the requested information | |
726 if (PrintNativeNMethods) { | |
727 print_code(); | |
6790
2cb2f30450c7
7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents:
6725
diff
changeset
|
728 if (oop_maps != NULL) { |
2cb2f30450c7
7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents:
6725
diff
changeset
|
729 oop_maps->print(); |
2cb2f30450c7
7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents:
6725
diff
changeset
|
730 } |
0 | 731 } |
732 if (PrintRelocations) { | |
733 print_relocations(); | |
734 } | |
735 if (xtty != NULL) { | |
736 xtty->tail("print_native_nmethod"); | |
737 } | |
738 } | |
739 } | |
740 | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
741 // For dtrace wrappers |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
742 #ifdef HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
743 nmethod::nmethod( |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
744 Method* method, |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
745 int nmethod_size, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
746 CodeOffsets* offsets, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
747 CodeBuffer* code_buffer, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
748 int frame_size) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
749 : CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod), |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
750 nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL), |
2019 | 751 _native_receiver_sp_offset(in_ByteSize(-1)), |
752 _native_basic_lock_sp_offset(in_ByteSize(-1)) | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
753 { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
754 { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
755 debug_only(No_Safepoint_Verifier nsv;) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
756 assert_locked_or_safepoint(CodeCache_lock); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
757 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
758 init_defaults(); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
759 _method = method; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
760 _entry_bci = InvocationEntryBci; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
761 // We have no exception handler or deopt handler make the |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
762 // values something that will never match a pc like the nmethod vtable entry |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
763 _exception_offset = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
764 _deoptimize_offset = 0; |
1204 | 765 _deoptimize_mh_offset = 0; |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1253
diff
changeset
|
766 _unwind_handler_offset = -1; |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
767 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
768 _orig_pc_offset = 0; |
1748 | 769 _consts_offset = data_offset(); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
770 _stub_offset = data_offset(); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
771 _oops_offset = data_offset(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
772 _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
773 _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
774 _scopes_pcs_offset = _scopes_data_offset; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
775 _dependencies_offset = _scopes_pcs_offset; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
776 _handler_table_offset = _dependencies_offset; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
777 _nul_chk_table_offset = _handler_table_offset; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
778 _nmethod_end_offset = _nul_chk_table_offset; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
779 _compile_id = 0; // default |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
780 _comp_level = CompLevel_none; |
1748 | 781 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
782 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
783 _osr_entry_point = NULL; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
784 _exception_cache = NULL; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
785 _pc_desc_cache.reset_to(NULL); |
12324
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
786 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
787 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
788 code_buffer->copy_values_to(this); |
20191
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
789 if (ScavengeRootsInCode) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
790 if (detect_scavenge_root_oops()) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
791 CodeCache::add_scavenge_root_nmethod(this); |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
792 } |
17915
e0a77b91da68
8040085: dtrace/jsdt tests crash on solaris. found an unadvertised bad scavengable oop in the code cache
anoll
parents:
17810
diff
changeset
|
793 Universe::heap()->register_nmethod(this); |
e0a77b91da68
8040085: dtrace/jsdt tests crash on solaris. found an unadvertised bad scavengable oop in the code cache
anoll
parents:
17810
diff
changeset
|
794 } |
e0a77b91da68
8040085: dtrace/jsdt tests crash on solaris. found an unadvertised bad scavengable oop in the code cache
anoll
parents:
17810
diff
changeset
|
795 DEBUG_ONLY(verify_scavenge_root_oops();) |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
796 CodeCache::commit(this); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
797 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
798 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
799 if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
800 ttyLocker ttyl; // keep the following output all in one block |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
801 // This output goes directly to the tty, not the compiler log. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
802 // To enable tools to match it up with the compilation activity, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
803 // be sure to tag this tty output with the compile ID. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
804 if (xtty != NULL) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
805 xtty->begin_head("print_dtrace_nmethod"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
806 xtty->method(_method); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
807 xtty->stamp(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
808 xtty->end_head(" address='" INTPTR_FORMAT "'", (intptr_t) this); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
809 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
810 // print the header part first |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
811 print(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
812 // then print the requested information |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
813 if (PrintNMethods) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
814 print_code(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
815 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
816 if (PrintRelocations) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
817 print_relocations(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
818 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
819 if (xtty != NULL) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
820 xtty->tail("print_dtrace_nmethod"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
821 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
822 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
823 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
100
diff
changeset
|
824 #endif // def HAVE_DTRACE_H |
0 | 825 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
12080
diff
changeset
|
826 void* nmethod::operator new(size_t size, int nmethod_size) throw() { |
10114
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
827 // Not critical, may return null if there is too little continuous memory |
a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
neliasso
parents:
8864
diff
changeset
|
828 return CodeCache::allocate(nmethod_size); |
0 | 829 } |
830 | |
831 nmethod::nmethod( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
832 Method* method, |
0 | 833 int nmethod_size, |
834 int compile_id, | |
835 int entry_bci, | |
836 CodeOffsets* offsets, | |
837 int orig_pc_offset, | |
838 DebugInformationRecorder* debug_info, | |
839 Dependencies* dependencies, | |
840 CodeBuffer *code_buffer, | |
841 int frame_size, | |
842 OopMapSet* oop_maps, | |
843 ExceptionHandlerTable* handler_table, | |
844 ImplicitExceptionTable* nul_chk_table, | |
845 AbstractCompiler* compiler, | |
846 int comp_level | |
847 ) | |
848 : CodeBlob("nmethod", code_buffer, sizeof(nmethod), | |
849 nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), | |
2019 | 850 _native_receiver_sp_offset(in_ByteSize(-1)), |
851 _native_basic_lock_sp_offset(in_ByteSize(-1)) | |
0 | 852 { |
853 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); | |
854 { | |
855 debug_only(No_Safepoint_Verifier nsv;) | |
856 assert_locked_or_safepoint(CodeCache_lock); | |
857 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
858 init_defaults(); |
0 | 859 _method = method; |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
860 _entry_bci = entry_bci; |
0 | 861 _compile_id = compile_id; |
862 _comp_level = comp_level; | |
863 _compiler = compiler; | |
864 _orig_pc_offset = orig_pc_offset; | |
12324
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
865 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
1748 | 866 |
867 // Section offsets | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
868 _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
869 _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); |
0 | 870 |
871 // Exception handler and deopt handler are in the stub section | |
2083
7d9caaedafce
6990933: assert(sender_cb) failed: sanity in frame::sender_for_interpreter_frame
twisti
parents:
1972
diff
changeset
|
872 assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set"); |
7d9caaedafce
6990933: assert(sender_cb) failed: sanity in frame::sender_for_interpreter_frame
twisti
parents:
1972
diff
changeset
|
873 assert(offsets->value(CodeOffsets::Deopt ) != -1, "must be set"); |
1748 | 874 _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); |
875 _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); | |
2083
7d9caaedafce
6990933: assert(sender_cb) failed: sanity in frame::sender_for_interpreter_frame
twisti
parents:
1972
diff
changeset
|
876 if (offsets->value(CodeOffsets::DeoptMH) != -1) { |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
877 _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
878 } else { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
879 _deoptimize_mh_offset = -1; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
880 } |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1253
diff
changeset
|
881 if (offsets->value(CodeOffsets::UnwindHandler) != -1) { |
1748 | 882 _unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler); |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1253
diff
changeset
|
883 } else { |
1748 | 884 _unwind_handler_offset = -1; |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1253
diff
changeset
|
885 } |
1748 | 886 |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
887 _oops_offset = data_offset(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
888 _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
889 _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
890 |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
891 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); |
0 | 892 _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); |
893 _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); | |
894 _nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize); | |
895 _nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize); | |
896 | |
1748 | 897 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
898 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); | |
899 _osr_entry_point = code_begin() + offsets->value(CodeOffsets::OSR_Entry); | |
0 | 900 _exception_cache = NULL; |
901 _pc_desc_cache.reset_to(scopes_pcs_begin()); | |
902 | |
903 // Copy contents of ScopeDescRecorder to nmethod | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
904 code_buffer->copy_values_to(this); |
0 | 905 debug_info->copy_to(this); |
906 dependencies->copy_to(this); | |
20191
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
907 if (ScavengeRootsInCode) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
908 if (detect_scavenge_root_oops()) { |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
909 CodeCache::add_scavenge_root_nmethod(this); |
fd81a5764900
8046231: G1: Code root location ... from nmethod ... not in strong code roots for region
pliden
parents:
17937
diff
changeset
|
910 } |
12080 | 911 Universe::heap()->register_nmethod(this); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
912 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
913 debug_only(verify_scavenge_root_oops()); |
0 | 914 |
915 CodeCache::commit(this); | |
916 | |
917 // Copy contents of ExceptionHandlerTable to nmethod | |
918 handler_table->copy_to(this); | |
919 nul_chk_table->copy_to(this); | |
920 | |
921 // we use the information of entry points to find out if a method is | |
922 // static or non static | |
923 assert(compiler->is_c2() || | |
924 _method->is_static() == (entry_point() == _verified_entry_point), | |
925 " entry points must be same for static methods and vice versa"); | |
926 } | |
927 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
928 bool printnmethods = PrintNMethods |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
929 || CompilerOracle::should_print(_method) |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
930 || CompilerOracle::has_option_string(_method, "PrintNMethods"); |
0 | 931 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { |
932 print_nmethod(printnmethods); | |
933 } | |
934 } | |
935 | |
936 | |
937 // Print a short set of xml attributes to identify this nmethod. The | |
938 // output should be embedded in some other element. | |
939 void nmethod::log_identity(xmlStream* log) const { | |
940 log->print(" compile_id='%d'", compile_id()); | |
941 const char* nm_kind = compile_kind(); | |
942 if (nm_kind != NULL) log->print(" compile_kind='%s'", nm_kind); | |
943 if (compiler() != NULL) { | |
944 log->print(" compiler='%s'", compiler()->name()); | |
945 } | |
1783 | 946 if (TieredCompilation) { |
947 log->print(" level='%d'", comp_level()); | |
948 } | |
0 | 949 } |
950 | |
951 | |
952 #define LOG_OFFSET(log, name) \ | |
953 if ((intptr_t)name##_end() - (intptr_t)name##_begin()) \ | |
954 log->print(" " XSTR(name) "_offset='%d'" , \ | |
955 (intptr_t)name##_begin() - (intptr_t)this) | |
956 | |
957 | |
958 void nmethod::log_new_nmethod() const { | |
959 if (LogCompilation && xtty != NULL) { | |
960 ttyLocker ttyl; | |
961 HandleMark hm; | |
962 xtty->begin_elem("nmethod"); | |
963 log_identity(xtty); | |
1748 | 964 xtty->print(" entry='" INTPTR_FORMAT "' size='%d'", code_begin(), size()); |
0 | 965 xtty->print(" address='" INTPTR_FORMAT "'", (intptr_t) this); |
966 | |
967 LOG_OFFSET(xtty, relocation); | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
968 LOG_OFFSET(xtty, consts); |
1748 | 969 LOG_OFFSET(xtty, insts); |
0 | 970 LOG_OFFSET(xtty, stub); |
971 LOG_OFFSET(xtty, scopes_data); | |
972 LOG_OFFSET(xtty, scopes_pcs); | |
973 LOG_OFFSET(xtty, dependencies); | |
974 LOG_OFFSET(xtty, handler_table); | |
975 LOG_OFFSET(xtty, nul_chk_table); | |
976 LOG_OFFSET(xtty, oops); | |
977 | |
978 xtty->method(method()); | |
979 xtty->stamp(); | |
980 xtty->end_elem(); | |
981 } | |
982 } | |
983 | |
984 #undef LOG_OFFSET | |
985 | |
986 | |
987 // Print out more verbose output usually for a newly created nmethod. | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
988 void nmethod::print_on(outputStream* st, const char* msg) const { |
0 | 989 if (st != NULL) { |
990 ttyLocker ttyl; | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
991 if (WizardMode) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
992 CompileTask::print_compilation(st, this, msg, /*short_form:*/ true); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
993 st->print_cr(" (" INTPTR_FORMAT ")", this); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
994 } else { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
995 CompileTask::print_compilation(st, this, msg, /*short_form:*/ false); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
996 } |
0 | 997 } |
998 } | |
999 | |
1000 | |
1001 void nmethod::print_nmethod(bool printmethod) { | |
1002 ttyLocker ttyl; // keep the following output all in one block | |
1003 if (xtty != NULL) { | |
1004 xtty->begin_head("print_nmethod"); | |
1005 xtty->stamp(); | |
1006 xtty->end_head(); | |
1007 } | |
1008 // print the header part first | |
1009 print(); | |
1010 // then print the requested information | |
1011 if (printmethod) { | |
1012 print_code(); | |
1013 print_pcs(); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
1014 if (oop_maps()) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
1015 oop_maps()->print(); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4873
diff
changeset
|
1016 } |
0 | 1017 } |
1018 if (PrintDebugInfo) { | |
1019 print_scopes(); | |
1020 } | |
1021 if (PrintRelocations) { | |
1022 print_relocations(); | |
1023 } | |
1024 if (PrintDependencies) { | |
1025 print_dependencies(); | |
1026 } | |
1027 if (PrintExceptionHandlers) { | |
1028 print_handler_table(); | |
1029 print_nul_chk_table(); | |
1030 } | |
1031 if (xtty != NULL) { | |
1032 xtty->tail("print_nmethod"); | |
1033 } | |
1034 } | |
1035 | |
1036 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1037 // Promote one word from an assembly-time handle to a live embedded oop. |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1038 inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1039 if (handle == NULL || |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1040 // As a special case, IC oops are initialized to 1 or -1. |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1041 handle == (jobject) Universe::non_oop_word()) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1042 (*dest) = (oop) handle; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1043 } else { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1044 (*dest) = JNIHandles::resolve_non_null(handle); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1045 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1046 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1047 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1048 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1049 // Have to have the same name because it's called by a template |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1050 void nmethod::copy_values(GrowableArray<jobject>* array) { |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1051 int length = array->length(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1052 assert((address)(oops_begin() + length) <= (address)oops_end(), "oops big enough"); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1053 oop* dest = oops_begin(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1054 for (int index = 0 ; index < length; index++) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1055 initialize_immediate_oop(&dest[index], array->at(index)); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1056 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1057 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1058 // Now we can fix up all the oops in the code. We need to do this |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1059 // in the code because the assembler uses jobjects as placeholders. |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1060 // The code and relocations have already been initialized by the |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1061 // CodeBlob constructor, so it is valid even at this early point to |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1062 // iterate over relocations and patch the code. |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1063 fix_oop_relocations(NULL, NULL, /*initialize_immediates=*/ true); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1064 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1065 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1066 void nmethod::copy_values(GrowableArray<Metadata*>* array) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1067 int length = array->length(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1068 assert((address)(metadata_begin() + length) <= (address)metadata_end(), "big enough"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1069 Metadata** dest = metadata_begin(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1070 for (int index = 0 ; index < length; index++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1071 dest[index] = array->at(index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1072 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1073 } |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1074 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1075 bool nmethod::is_at_poll_return(address pc) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1076 RelocIterator iter(this, pc, pc+1); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1077 while (iter.next()) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1078 if (iter.type() == relocInfo::poll_return_type) |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1079 return true; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1080 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1081 return false; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1082 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1083 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1084 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1085 bool nmethod::is_at_poll_or_poll_return(address pc) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1086 RelocIterator iter(this, pc, pc+1); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1087 while (iter.next()) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1088 relocInfo::relocType t = iter.type(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1089 if (t == relocInfo::poll_return_type || t == relocInfo::poll_type) |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1090 return true; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1091 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1092 return false; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1093 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1094 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1095 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1096 void nmethod::fix_oop_relocations(address begin, address end, bool initialize_immediates) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1097 // re-patch all oop-bearing instructions, just in case some oops moved |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1098 RelocIterator iter(this, begin, end); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1099 while (iter.next()) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1100 if (iter.type() == relocInfo::oop_type) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1101 oop_Relocation* reloc = iter.oop_reloc(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1102 if (initialize_immediates && reloc->oop_is_immediate()) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1103 oop* dest = reloc->oop_addr(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1104 initialize_immediate_oop(dest, (jobject) *dest); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1105 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1106 // Refresh the oop-related bits of this instruction. |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1107 reloc->fix_oop_relocation(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1108 } else if (iter.type() == relocInfo::metadata_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1109 metadata_Relocation* reloc = iter.metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1110 reloc->fix_metadata_relocation(); |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1111 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1112 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1113 } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1114 |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
1115 |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1116 void nmethod::verify_oop_relocations() { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1117 // Ensure sure that the code matches the current oop values |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1118 RelocIterator iter(this, NULL, NULL); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1119 while (iter.next()) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1120 if (iter.type() == relocInfo::oop_type) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1121 oop_Relocation* reloc = iter.oop_reloc(); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1122 if (!reloc->oop_is_immediate()) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1123 reloc->verify_oop_relocation(); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1124 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1125 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1126 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1127 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1128 |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2360
diff
changeset
|
1129 |
0 | 1130 ScopeDesc* nmethod::scope_desc_at(address pc) { |
1131 PcDesc* pd = pc_desc_at(pc); | |
1132 guarantee(pd != NULL, "scope must be present"); | |
1133 return new ScopeDesc(this, pd->scope_decode_offset(), | |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
1134 pd->obj_decode_offset(), pd->should_reexecute(), |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
1135 pd->return_oop()); |
0 | 1136 } |
1137 | |
1138 | |
1139 void nmethod::clear_inline_caches() { | |
1140 assert(SafepointSynchronize::is_at_safepoint(), "cleaning of IC's only allowed at safepoint"); | |
1141 if (is_zombie()) { | |
1142 return; | |
1143 } | |
1144 | |
1145 RelocIterator iter(this); | |
1146 while (iter.next()) { | |
1147 iter.reloc()->clear_inline_cache(); | |
1148 } | |
1149 } | |
1150 | |
1151 | |
1152 void nmethod::cleanup_inline_caches() { | |
1153 | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1154 assert_locked_or_safepoint(CompiledIC_lock); |
0 | 1155 |
1156 // If the method is not entrant or zombie then a JMP is plastered over the | |
1157 // first few bytes. If an oop in the old code was there, that oop | |
1158 // should not get GC'd. Skip the first few bytes of oops on | |
1159 // not-entrant methods. | |
1160 address low_boundary = verified_entry_point(); | |
1161 if (!is_in_use()) { | |
1162 low_boundary += NativeJump::instruction_size; | |
1163 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. | |
1164 // This means that the low_boundary is going to be a little too high. | |
1165 // This shouldn't matter, since oops of non-entrant methods are never used. | |
1166 // In fact, why are we bothering to look at oops in a non-entrant method?? | |
1167 } | |
1168 | |
1169 // Find all calls in an nmethod, and clear the ones that points to zombie methods | |
1170 ResourceMark rm; | |
1171 RelocIterator iter(this, low_boundary); | |
1172 while(iter.next()) { | |
1173 switch(iter.type()) { | |
1174 case relocInfo::virtual_call_type: | |
1175 case relocInfo::opt_virtual_call_type: { | |
20277
882004b9e7e1
8047362: Add a version of CompiledIC_at that doesn't create a new RelocIterator
stefank
parents:
20269
diff
changeset
|
1176 CompiledIC *ic = CompiledIC_at(&iter); |
0 | 1177 // Ok, to lookup references to zombies here |
1178 CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination()); | |
1179 if( cb != NULL && cb->is_nmethod() ) { | |
1180 nmethod* nm = (nmethod*)cb; | |
1181 // Clean inline caches pointing to both zombie and not_entrant methods | |
1202 | 1182 if (!nm->is_in_use() || (nm->method()->code() != nm)) ic->set_to_clean(); |
0 | 1183 } |
1184 break; | |
1185 } | |
1186 case relocInfo::static_call_type: { | |
1187 CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc()); | |
1188 CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination()); | |
1189 if( cb != NULL && cb->is_nmethod() ) { | |
1190 nmethod* nm = (nmethod*)cb; | |
1191 // Clean inline caches pointing to both zombie and not_entrant methods | |
1202 | 1192 if (!nm->is_in_use() || (nm->method()->code() != nm)) csc->set_to_clean(); |
0 | 1193 } |
1194 break; | |
1195 } | |
1196 } | |
1197 } | |
1198 } | |
1199 | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1200 void nmethod::verify_clean_inline_caches() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1201 assert_locked_or_safepoint(CompiledIC_lock); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1202 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1203 // If the method is not entrant or zombie then a JMP is plastered over the |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1204 // first few bytes. If an oop in the old code was there, that oop |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1205 // should not get GC'd. Skip the first few bytes of oops on |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1206 // not-entrant methods. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1207 address low_boundary = verified_entry_point(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1208 if (!is_in_use()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1209 low_boundary += NativeJump::instruction_size; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1210 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1211 // This means that the low_boundary is going to be a little too high. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1212 // This shouldn't matter, since oops of non-entrant methods are never used. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1213 // In fact, why are we bothering to look at oops in a non-entrant method?? |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1214 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1215 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1216 ResourceMark rm; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1217 RelocIterator iter(this, low_boundary); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1218 while(iter.next()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1219 switch(iter.type()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1220 case relocInfo::virtual_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1221 case relocInfo::opt_virtual_call_type: { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1222 CompiledIC *ic = CompiledIC_at(&iter); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1223 // Ok, to lookup references to zombies here |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1224 CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination()); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1225 if( cb != NULL && cb->is_nmethod() ) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1226 nmethod* nm = (nmethod*)cb; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1227 // Verify that inline caches pointing to both zombie and not_entrant methods are clean |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1228 if (!nm->is_in_use() || (nm->method()->code() != nm)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1229 assert(ic->is_clean(), "IC should be clean"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1230 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1231 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1232 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1233 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1234 case relocInfo::static_call_type: { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1235 CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc()); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1236 CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination()); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1237 if( cb != NULL && cb->is_nmethod() ) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1238 nmethod* nm = (nmethod*)cb; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1239 // Verify that inline caches pointing to both zombie and not_entrant methods are clean |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1240 if (!nm->is_in_use() || (nm->method()->code() != nm)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1241 assert(csc->is_clean(), "IC should be clean"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1242 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1243 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1244 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1245 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1246 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1247 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1248 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1249 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1250 int nmethod::verify_icholder_relocations() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1251 int count = 0; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1252 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1253 RelocIterator iter(this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1254 while(iter.next()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1255 if (iter.type() == relocInfo::virtual_call_type) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1256 if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1257 CompiledIC *ic = CompiledIC_at(&iter); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1258 if (TraceCompiledIC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1259 tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder())); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1260 ic->print(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1261 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1262 assert(ic->cached_icholder() != NULL, "must be non-NULL"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1263 count++; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1264 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1265 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1266 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1267 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1268 return count; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1269 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1270 |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1271 // This is a private interface with the sweeper. |
0 | 1272 void nmethod::mark_as_seen_on_stack() { |
12324
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1273 assert(is_alive(), "Must be an alive method"); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1274 // Set the traversal mark to ensure that the sweeper does 2 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1275 // cleaning passes before moving to zombie. |
0 | 1276 set_stack_traversal_mark(NMethodSweeper::traversal_count()); |
1277 } | |
1278 | |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1279 // Tell if a non-entrant method can be converted to a zombie (i.e., |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1280 // there are no activations on the stack, not in use by the VM, |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1281 // and not in use by the ServiceThread) |
0 | 1282 bool nmethod::can_not_entrant_be_converted() { |
1283 assert(is_not_entrant(), "must be a non-entrant method"); | |
1284 | |
1285 // Since the nmethod sweeper only does partial sweep the sweeper's traversal | |
1286 // count can be greater than the stack traversal count before it hits the | |
1287 // nmethod for the second time. | |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1288 return stack_traversal_mark()+1 < NMethodSweeper::traversal_count() && |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1289 !is_locked_by_vm(); |
0 | 1290 } |
1291 | |
1292 void nmethod::inc_decompile_count() { | |
1783 | 1293 if (!is_compiled_by_c2()) return; |
0 | 1294 // Could be gated by ProfileTraps, but do not bother... |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1295 Method* m = method(); |
0 | 1296 if (m == NULL) return; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1297 MethodData* mdo = m->method_data(); |
0 | 1298 if (mdo == NULL) return; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1299 // There is a benign race here. See comments in methodData.hpp. |
0 | 1300 mdo->inc_decompile_count(); |
1301 } | |
1302 | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1303 void nmethod::increase_unloading_clock() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1304 _global_unloading_clock++; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1305 if (_global_unloading_clock == 0) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1306 // _nmethods are allocated with _unloading_clock == 0, |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1307 // so 0 is never used as a clock value. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1308 _global_unloading_clock = 1; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1309 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1310 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1311 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1312 void nmethod::set_unloading_clock(unsigned char unloading_clock) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1313 OrderAccess::release_store((volatile jubyte*)&_unloading_clock, unloading_clock); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1314 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1315 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1316 unsigned char nmethod::unloading_clock() { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1317 return (unsigned char)OrderAccess::load_acquire((volatile jubyte*)&_unloading_clock); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1318 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1319 |
0 | 1320 void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) { |
1321 | |
1322 post_compiled_method_unload(); | |
1323 | |
1324 // Since this nmethod is being unloaded, make sure that dependencies | |
1325 // recorded in instanceKlasses get flushed and pass non-NULL closure to | |
1326 // indicate that this work is being done during a GC. | |
1327 assert(Universe::heap()->is_gc_active(), "should only be called during gc"); | |
1328 assert(is_alive != NULL, "Should be non-NULL"); | |
1329 // A non-NULL is_alive closure indicates that this is being called during GC. | |
1330 flush_dependencies(is_alive); | |
1331 | |
1332 // Break cycle between nmethod & method | |
1333 if (TraceClassUnloading && WizardMode) { | |
1334 tty->print_cr("[Class unloading: Making nmethod " INTPTR_FORMAT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1335 " unloadable], Method*(" INTPTR_FORMAT |
0 | 1336 "), cause(" INTPTR_FORMAT ")", |
1337 this, (address)_method, (address)cause); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1338 if (!Universe::heap()->is_gc_active()) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1339 cause->klass()->print(); |
0 | 1340 } |
941 | 1341 // Unlink the osr method, so we do not look this up again |
1342 if (is_osr_method()) { | |
1343 invalidate_osr_method(); | |
1344 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1345 // If _method is already NULL the Method* is about to be unloaded, |
0 | 1346 // so we don't have to break the cycle. Note that it is possible to |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1347 // have the Method* live here, in case we unload the nmethod because |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1348 // it is pointing to some oop (other than the Method*) being unloaded. |
0 | 1349 if (_method != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1350 // OSR methods point to the Method*, but the Method* does not |
0 | 1351 // point back! |
1352 if (_method->code() == this) { | |
1353 _method->clear_code(); // Break a cycle | |
1354 } | |
1355 _method = NULL; // Clear the method of this dead nmethod | |
1356 } | |
1357 // Make the class unloaded - i.e., change state and notify sweeper | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1358 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
0 | 1359 if (is_in_use()) { |
1360 // Transitioning directly from live to unloaded -- so | |
1361 // we need to force a cache clean-up; remember this | |
1362 // for later on. | |
1363 CodeCache::set_needs_cache_clean(true); | |
1364 } | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1365 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1366 // Unregister must be done before the state change |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1367 Universe::heap()->unregister_nmethod(this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1368 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1369 _state = unloaded; |
0 | 1370 |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1371 // Log the unloading. |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1372 log_state_change(); |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1373 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1374 // The Method* is gone at this point |
0 | 1375 assert(_method == NULL, "Tautology"); |
1376 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1377 set_osr_link(NULL); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1378 //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods |
13074
78da3894b86f
8027593: performance drop with constrained codecache starting with hs25 b111
anoll
parents:
13071
diff
changeset
|
1379 NMethodSweeper::report_state_change(this); |
0 | 1380 } |
1381 | |
1382 void nmethod::invalidate_osr_method() { | |
1383 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); | |
1384 // Remove from list of active nmethods | |
1385 if (method() != NULL) | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6806
diff
changeset
|
1386 method()->method_holder()->remove_osr_nmethod(this); |
0 | 1387 // Set entry as invalid |
1388 _entry_bci = InvalidOSREntryBci; | |
1389 } | |
1390 | |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1391 void nmethod::log_state_change() const { |
0 | 1392 if (LogCompilation) { |
1393 if (xtty != NULL) { | |
1394 ttyLocker ttyl; // keep the following output all in one block | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1395 if (_state == unloaded) { |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1396 xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'", |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1397 os::current_thread_id()); |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1398 } else { |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1399 xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s", |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1400 os::current_thread_id(), |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1401 (_state == zombie ? " zombie='1'" : "")); |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1402 } |
0 | 1403 log_identity(xtty); |
1404 xtty->stamp(); | |
1405 xtty->end_elem(); | |
1406 } | |
1407 } | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1408 if (PrintCompilation && _state != unloaded) { |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
1409 print_on(tty, _state == zombie ? "made zombie" : "made not entrant"); |
0 | 1410 } |
1411 } | |
1412 | |
13074
78da3894b86f
8027593: performance drop with constrained codecache starting with hs25 b111
anoll
parents:
13071
diff
changeset
|
1413 /** |
78da3894b86f
8027593: performance drop with constrained codecache starting with hs25 b111
anoll
parents:
13071
diff
changeset
|
1414 * Common functionality for both make_not_entrant and make_zombie |
78da3894b86f
8027593: performance drop with constrained codecache starting with hs25 b111
anoll
parents:
13071
diff
changeset
|
1415 */ |
1141 | 1416 bool nmethod::make_not_entrant_or_zombie(unsigned int state) { |
0 | 1417 assert(state == zombie || state == not_entrant, "must be zombie or not_entrant"); |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1418 assert(!is_zombie(), "should not already be a zombie"); |
0 | 1419 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1420 // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below. |
0 | 1421 nmethodLocker nml(this); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1422 methodHandle the_method(method()); |
1726 | 1423 No_Safepoint_Verifier nsv; |
0 | 1424 |
12080 | 1425 // during patching, depending on the nmethod state we must notify the GC that |
1426 // code has been unloaded, unregistering it. We cannot do this right while | |
1427 // holding the Patching_lock because we need to use the CodeCache_lock. This | |
1428 // would be prone to deadlocks. | |
1429 // This flag is used to remember whether we need to later lock and unregister. | |
1430 bool nmethod_needs_unregister = false; | |
1431 | |
0 | 1432 { |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1433 // invalidate osr nmethod before acquiring the patching lock since |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1434 // they both acquire leaf locks and we don't want a deadlock. |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1435 // This logic is equivalent to the logic below for patching the |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1436 // verified entry point of regular methods. |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1437 if (is_osr_method()) { |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1438 // this effectively makes the osr nmethod not entrant |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1439 invalidate_osr_method(); |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1440 } |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1441 |
0 | 1442 // Enter critical section. Does not block for safepoint. |
1443 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1444 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1445 if (_state == state) { |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1446 // another thread already performed this transition so nothing |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1447 // to do, but return false to indicate this. |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1448 return false; |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1449 } |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1450 |
0 | 1451 // The caller can be calling the method statically or through an inline |
1452 // cache call. | |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1453 if (!is_osr_method() && !is_not_entrant()) { |
0 | 1454 NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), |
1455 SharedRuntime::get_handle_wrong_method_stub()); | |
1456 } | |
1457 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1458 if (is_in_use()) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1459 // It's a true state change, so mark the method as decompiled. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1460 // Do it only for transition from alive. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1461 inc_decompile_count(); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1462 } |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1463 |
12080 | 1464 // If the state is becoming a zombie, signal to unregister the nmethod with |
1465 // the heap. | |
1466 // This nmethod may have already been unloaded during a full GC. | |
1467 if ((state == zombie) && !is_unloaded()) { | |
1468 nmethod_needs_unregister = true; | |
1469 } | |
1470 | |
12324
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1471 // Must happen before state change. Otherwise we have a race condition in |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1472 // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1473 // transition its state from 'not_entrant' to 'zombie' without having to wait |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1474 // for stack scanning. |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1475 if (state == not_entrant) { |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1476 mark_as_seen_on_stack(); |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1477 OrderAccess::storestore(); |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1478 } |
510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
anoll
parents:
12175
diff
changeset
|
1479 |
0 | 1480 // Change state |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1481 _state = state; |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1482 |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1483 // Log the transition once |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1484 log_state_change(); |
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1485 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1486 // Remove nmethod from method. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1487 // We need to check if both the _code and _from_compiled_code_entry_point |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1488 // refer to this nmethod because there is a race in setting these two fields |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1489 // in Method* as seen in bugid 4947125. |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1490 // If the vep() points to the zombie nmethod, the memory for the nmethod |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1491 // could be flushed and the compiler and vtable stubs could still call |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1492 // through it. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1493 if (method() != NULL && (method()->code() == this || |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1494 method()->from_compiled_entry() == verified_entry_point())) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1495 HandleMark hm; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1496 method()->clear_code(); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1497 } |
0 | 1498 } // leave critical region under Patching_lock |
1499 | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1500 // When the nmethod becomes zombie it is no longer alive so the |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1501 // dependencies must be flushed. nmethods in the not_entrant |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1502 // state will be flushed later when the transition to zombie |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1503 // happens or they get unloaded. |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1504 if (state == zombie) { |
1726 | 1505 { |
1506 // Flushing dependecies must be done before any possible | |
1507 // safepoint can sneak in, otherwise the oops used by the | |
1508 // dependency logic could have become stale. | |
1509 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
12080 | 1510 if (nmethod_needs_unregister) { |
1511 Universe::heap()->unregister_nmethod(this); | |
1512 } | |
1726 | 1513 flush_dependencies(NULL); |
1514 } | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1616
diff
changeset
|
1515 |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1516 // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1517 // event and it hasn't already been reported for this nmethod then |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1518 // report it now. The event may have been reported earilier if the GC |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1519 // marked it for unloading). JvmtiDeferredEventQueue support means |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1520 // we no longer go to a safepoint here. |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1521 post_compiled_method_unload(); |
1726 | 1522 |
1523 #ifdef ASSERT | |
1524 // It's no longer safe to access the oops section since zombie | |
1525 // nmethods aren't scanned for GC. | |
1526 _oops_are_stale = true; | |
1527 #endif | |
12161
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
1528 // the Method may be reclaimed by class unloading now that the |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
1529 // nmethod is in zombie state |
e1fbb86b47e4
8016277: Crash in nmethod::is_compiled_by_c1() on x86
roland
parents:
12080
diff
changeset
|
1530 set_method(NULL); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1531 } else { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1532 assert(state == not_entrant, "other cases may need to be handled differently"); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1533 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1534 |
0 | 1535 if (TraceCreateZombies) { |
1536 tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie"); | |
1537 } | |
1538 | |
13074
78da3894b86f
8027593: performance drop with constrained codecache starting with hs25 b111
anoll
parents:
13071
diff
changeset
|
1539 NMethodSweeper::report_state_change(this); |
1109
032260830071
5057818: codecache full and compiler disabled in bigapps fastdebug run
never
parents:
994
diff
changeset
|
1540 return true; |
0 | 1541 } |
1542 | |
1543 void nmethod::flush() { | |
1544 // Note that there are no valid oops in the nmethod anymore. | |
1545 assert(is_zombie() || (is_osr_method() && is_unloaded()), "must be a zombie method"); | |
1546 assert(is_marked_for_reclamation() || (is_osr_method() && is_unloaded()), "must be marked for reclamation"); | |
1547 | |
1548 assert (!is_locked_by_vm(), "locked methods shouldn't be flushed"); | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1549 assert_locked_or_safepoint(CodeCache_lock); |
0 | 1550 |
1551 // completely deallocate this method | |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4006
diff
changeset
|
1552 Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, this); |
0 | 1553 if (PrintMethodFlushing) { |
1202 | 1554 tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", |
1555 _compile_id, this, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()/1024); | |
0 | 1556 } |
1557 | |
1558 // We need to deallocate any ExceptionCache data. | |
1559 // Note that we do not need to grab the nmethod lock for this, it | |
1560 // better be thread safe if we're disposing of it! | |
1561 ExceptionCache* ec = exception_cache(); | |
1562 set_exception_cache(NULL); | |
1563 while(ec != NULL) { | |
1564 ExceptionCache* next = ec->next(); | |
1565 delete ec; | |
1566 ec = next; | |
1567 } | |
1568 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1569 if (on_scavenge_root_list()) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1570 CodeCache::drop_scavenge_root_nmethod(this); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1571 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1572 |
1692 | 1573 #ifdef SHARK |
1845
a222fcfba398
6990549: Zero and Shark fixes after 6978355 and 6953144
twisti
parents:
1784
diff
changeset
|
1574 ((SharkCompiler *) compiler())->free_compiled_method(insts_begin()); |
1692 | 1575 #endif // SHARK |
1576 | |
0 | 1577 ((CodeBlob*)(this))->flush(); |
1578 | |
1579 CodeCache::free(this); | |
1580 } | |
1581 | |
1582 | |
1583 // | |
1584 // Notify all classes this nmethod is dependent on that it is no | |
1585 // longer dependent. This should only be called in two situations. | |
1586 // First, when a nmethod transitions to a zombie all dependents need | |
1587 // to be clear. Since zombification happens at a safepoint there's no | |
1588 // synchronization issues. The second place is a little more tricky. | |
1589 // During phase 1 of mark sweep class unloading may happen and as a | |
1590 // result some nmethods may get unloaded. In this case the flushing | |
1591 // of dependencies must happen during phase 1 since after GC any | |
1592 // dependencies in the unloaded nmethod won't be updated, so | |
1593 // traversing the dependency information in unsafe. In that case this | |
1594 // function is called with a non-NULL argument and this function only | |
1595 // notifies instanceKlasses that are reachable | |
1596 | |
1597 void nmethod::flush_dependencies(BoolObjectClosure* is_alive) { | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1490
diff
changeset
|
1598 assert_locked_or_safepoint(CodeCache_lock); |
0 | 1599 assert(Universe::heap()->is_gc_active() == (is_alive != NULL), |
1600 "is_alive is non-NULL if and only if we are called during GC"); | |
1601 if (!has_flushed_dependencies()) { | |
1602 set_has_flushed_dependencies(); | |
1603 for (Dependencies::DepStream deps(this); deps.next(); ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1604 Klass* klass = deps.context_type(); |
0 | 1605 if (klass == NULL) continue; // ignore things like evol_method |
1606 | |
1607 // During GC the is_alive closure is non-NULL, and is used to | |
1608 // determine liveness of dependees that need to be updated. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1609 if (is_alive == NULL || klass->is_loader_alive(is_alive)) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1610 InstanceKlass::cast(klass)->remove_dependent_nmethod(this); |
0 | 1611 } |
1612 } | |
1613 } | |
1614 } | |
1615 | |
1616 | |
1617 // If this oop is not live, the nmethod can be unloaded. | |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
1618 bool nmethod::can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred) { |
0 | 1619 assert(root != NULL, "just checking"); |
1620 oop obj = *root; | |
1621 if (obj == NULL || is_alive->do_object_b(obj)) { | |
1622 return false; | |
1623 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1624 |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1625 // If ScavengeRootsInCode is true, an nmethod might be unloaded |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1626 // simply because one of its constant oops has gone dead. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1627 // No actual classes need to be unloaded in order for this to occur. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
1628 assert(unloading_occurred || ScavengeRootsInCode, "Inconsistency in unloading"); |
0 | 1629 make_unloaded(is_alive, obj); |
1630 return true; | |
1631 } | |
1632 | |
1633 // ------------------------------------------------------------------ | |
1634 // post_compiled_method_load_event | |
1635 // new method for install_code() path | |
1636 // Transfer information from compilation to jvmti | |
1637 void nmethod::post_compiled_method_load_event() { | |
1638 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1639 Method* moop = method(); |
4006 | 1640 #ifndef USDT2 |
0 | 1641 HS_DTRACE_PROBE8(hotspot, compiled__method__load, |
1642 moop->klass_name()->bytes(), | |
1643 moop->klass_name()->utf8_length(), | |
1644 moop->name()->bytes(), | |
1645 moop->name()->utf8_length(), | |
1646 moop->signature()->bytes(), | |
1647 moop->signature()->utf8_length(), | |
1748 | 1648 insts_begin(), insts_size()); |
4006 | 1649 #else /* USDT2 */ |
1650 HOTSPOT_COMPILED_METHOD_LOAD( | |
1651 (char *) moop->klass_name()->bytes(), | |
1652 moop->klass_name()->utf8_length(), | |
1653 (char *) moop->name()->bytes(), | |
1654 moop->name()->utf8_length(), | |
1655 (char *) moop->signature()->bytes(), | |
1656 moop->signature()->utf8_length(), | |
1657 insts_begin(), insts_size()); | |
1658 #endif /* USDT2 */ | |
0 | 1659 |
1616
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1660 if (JvmtiExport::should_post_compiled_method_load() || |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1661 JvmtiExport::should_post_compiled_method_unload()) { |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1662 get_and_cache_jmethod_id(); |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1663 } |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1664 |
0 | 1665 if (JvmtiExport::should_post_compiled_method_load()) { |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1666 // Let the Service thread (which is a real Java thread) post the event |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1667 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1668 JvmtiDeferredEventQueue::enqueue( |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1669 JvmtiDeferredEvent::compiled_method_load_event(this)); |
0 | 1670 } |
1671 } | |
1672 | |
1616
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1673 jmethodID nmethod::get_and_cache_jmethod_id() { |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1674 if (_jmethod_id == NULL) { |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1675 // Cache the jmethod_id since it can no longer be looked up once the |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1676 // method itself has been marked for unloading. |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1677 _jmethod_id = method()->jmethod_id(); |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1678 } |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1679 return _jmethod_id; |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1680 } |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1681 |
0 | 1682 void nmethod::post_compiled_method_unload() { |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1683 if (unload_reported()) { |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1684 // During unloading we transition to unloaded and then to zombie |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1685 // and the unloading is reported during the first transition. |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1686 return; |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1687 } |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1563
diff
changeset
|
1688 |
0 | 1689 assert(_method != NULL && !is_unloaded(), "just checking"); |
1690 DTRACE_METHOD_UNLOAD_PROBE(method()); | |
1691 | |
1692 // If a JVMTI agent has enabled the CompiledMethodUnload event then | |
1616
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1693 // post the event. Sometime later this nmethod will be made a zombie |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1694 // by the sweeper but the Method* will not be valid at that point. |
1616
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1695 // If the _jmethod_id is null then no load event was ever requested |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1696 // so don't bother posting the unload. The main reason for this is |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1697 // that the jmethodID is a weak reference to the Method* so if |
1616
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1698 // it's being unloaded there's no way to look it up since the weak |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1699 // ref will have been cleared. |
38e8278318ca
6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs")
never
parents:
1602
diff
changeset
|
1700 if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) { |
0 | 1701 assert(!unload_reported(), "already unloaded"); |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1702 JvmtiDeferredEvent event = |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
1703 JvmtiDeferredEvent::compiled_method_unload_event(this, |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1704 _jmethod_id, insts_begin()); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1705 if (SafepointSynchronize::is_at_safepoint()) { |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1706 // Don't want to take the queueing lock. Add it as pending and |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1707 // it will get enqueued later. |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1708 JvmtiDeferredEventQueue::add_pending_event(event); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1709 } else { |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1710 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1711 JvmtiDeferredEventQueue::enqueue(event); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1712 } |
0 | 1713 } |
1714 | |
1715 // The JVMTI CompiledMethodUnload event can be enabled or disabled at | |
1716 // any time. As the nmethod is being unloaded now we mark it has | |
1717 // having the unload event reported - this will ensure that we don't | |
1718 // attempt to report the event in the unlikely scenario where the | |
1719 // event is enabled at the time the nmethod is made a zombie. | |
1720 set_unload_reported(); | |
1721 } | |
1722 | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1723 void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1724 if (ic->is_icholder_call()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1725 // The only exception is compiledICHolder oops which may |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1726 // yet be marked below. (We check this further below). |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1727 CompiledICHolder* cichk_oop = ic->cached_icholder(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1728 if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) && |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1729 cichk_oop->holder_klass()->is_loader_alive(is_alive)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1730 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1731 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1732 } else { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1733 Metadata* ic_oop = ic->cached_metadata(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1734 if (ic_oop != NULL) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1735 if (ic_oop->is_klass()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1736 if (((Klass*)ic_oop)->is_loader_alive(is_alive)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1737 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1738 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1739 } else if (ic_oop->is_method()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1740 if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1741 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1742 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1743 } else { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1744 ShouldNotReachHere(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1745 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1746 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1747 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1748 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1749 ic->set_to_clean(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1750 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1751 |
0 | 1752 // This is called at the end of the strong tracing/marking phase of a |
1753 // GC to unload an nmethod if it contains otherwise unreachable | |
1754 // oops. | |
1755 | |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
1756 void nmethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) { |
0 | 1757 // Make sure the oop's ready to receive visitors |
1758 assert(!is_zombie() && !is_unloaded(), | |
1759 "should not call follow on zombie or unloaded nmethod"); | |
1760 | |
1761 // If the method is not entrant then a JMP is plastered over the | |
1762 // first few bytes. If an oop in the old code was there, that oop | |
1763 // should not get GC'd. Skip the first few bytes of oops on | |
1764 // not-entrant methods. | |
1765 address low_boundary = verified_entry_point(); | |
1766 if (is_not_entrant()) { | |
1767 low_boundary += NativeJump::instruction_size; | |
1768 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. | |
1769 // (See comment above.) | |
1770 } | |
1771 | |
1772 // The RedefineClasses() API can cause the class unloading invariant | |
1773 // to no longer be true. See jvmtiExport.hpp for details. | |
1774 // Also, leave a debugging breadcrumb in local flag. | |
1775 bool a_class_was_redefined = JvmtiExport::has_redefined_a_class(); | |
1776 if (a_class_was_redefined) { | |
1777 // This set of the unloading_occurred flag is done before the | |
1778 // call to post_compiled_method_unload() so that the unloading | |
1779 // of this nmethod is reported. | |
1780 unloading_occurred = true; | |
1781 } | |
1782 | |
1783 // Exception cache | |
20269 | 1784 clean_exception_cache(is_alive); |
0 | 1785 |
1786 // If class unloading occurred we first iterate over all inline caches and | |
1787 // clear ICs where the cached oop is referring to an unloaded klass or method. | |
1788 // The remaining live cached oops will be traversed in the relocInfo::oop_type | |
1789 // iteration below. | |
1790 if (unloading_occurred) { | |
1791 RelocIterator iter(this, low_boundary); | |
1792 while(iter.next()) { | |
1793 if (iter.type() == relocInfo::virtual_call_type) { | |
20277
882004b9e7e1
8047362: Add a version of CompiledIC_at that doesn't create a new RelocIterator
stefank
parents:
20269
diff
changeset
|
1794 CompiledIC *ic = CompiledIC_at(&iter); |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1795 clean_ic_if_metadata_is_dead(ic, is_alive); |
0 | 1796 } |
1797 } | |
1798 } | |
1799 | |
1800 // Compiled code | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1801 { |
0 | 1802 RelocIterator iter(this, low_boundary); |
1803 while (iter.next()) { | |
1804 if (iter.type() == relocInfo::oop_type) { | |
1805 oop_Relocation* r = iter.oop_reloc(); | |
1806 // In this loop, we must only traverse those oops directly embedded in | |
1807 // the code. Other oops (oop_index>0) are seen as part of scopes_oops. | |
1808 assert(1 == (r->oop_is_immediate()) + | |
1809 (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), | |
1810 "oop must be found in exactly one place"); | |
1811 if (r->oop_is_immediate() && r->oop_value() != NULL) { | |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
1812 if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) { |
0 | 1813 return; |
1814 } | |
1815 } | |
1816 } | |
1817 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1818 } |
0 | 1819 |
1820 | |
1821 // Scopes | |
1822 for (oop* p = oops_begin(); p < oops_end(); p++) { | |
1823 if (*p == Universe::non_oop_word()) continue; // skip non-oops | |
6787
8966c2d65d96
7200470: KeepAliveClosure not needed in CodeCache::do_unloading
brutisso
parents:
6725
diff
changeset
|
1824 if (can_unload(is_alive, p, unloading_occurred)) { |
0 | 1825 return; |
1826 } | |
1827 } | |
1828 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1829 // Ensure that all metadata is still alive |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1830 verify_metadata_loaders(low_boundary, is_alive); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1831 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1832 |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1833 template <class CompiledICorStaticCall> |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1834 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, nmethod* from) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1835 // Ok, to lookup references to zombies here |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1836 CodeBlob *cb = CodeCache::find_blob_unsafe(addr); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1837 if (cb != NULL && cb->is_nmethod()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1838 nmethod* nm = (nmethod*)cb; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1839 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1840 if (nm->unloading_clock() != nmethod::global_unloading_clock()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1841 // The nmethod has not been processed yet. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1842 return true; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1843 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1844 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1845 // Clean inline caches pointing to both zombie and not_entrant methods |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1846 if (!nm->is_in_use() || (nm->method()->code() != nm)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1847 ic->set_to_clean(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1848 assert(ic->is_clean(), err_msg("nmethod " PTR_FORMAT "not clean %s", from, from->method()->name_and_sig_as_C_string())); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1849 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1850 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1851 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1852 return false; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1853 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1854 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1855 static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, BoolObjectClosure *is_alive, nmethod* from) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1856 return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), is_alive, from); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1857 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1858 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1859 static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, BoolObjectClosure *is_alive, nmethod* from) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1860 return clean_if_nmethod_is_unloaded(csc, csc->destination(), is_alive, from); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1861 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1862 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1863 bool nmethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1864 ResourceMark rm; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1865 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1866 // Make sure the oop's ready to receive visitors |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1867 assert(!is_zombie() && !is_unloaded(), |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1868 "should not call follow on zombie or unloaded nmethod"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1869 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1870 // If the method is not entrant then a JMP is plastered over the |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1871 // first few bytes. If an oop in the old code was there, that oop |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1872 // should not get GC'd. Skip the first few bytes of oops on |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1873 // not-entrant methods. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1874 address low_boundary = verified_entry_point(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1875 if (is_not_entrant()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1876 low_boundary += NativeJump::instruction_size; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1877 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1878 // (See comment above.) |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1879 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1880 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1881 // The RedefineClasses() API can cause the class unloading invariant |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1882 // to no longer be true. See jvmtiExport.hpp for details. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1883 // Also, leave a debugging breadcrumb in local flag. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1884 bool a_class_was_redefined = JvmtiExport::has_redefined_a_class(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1885 if (a_class_was_redefined) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1886 // This set of the unloading_occurred flag is done before the |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1887 // call to post_compiled_method_unload() so that the unloading |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1888 // of this nmethod is reported. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1889 unloading_occurred = true; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1890 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1891 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1892 // Exception cache |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1893 clean_exception_cache(is_alive); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1894 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1895 bool is_unloaded = false; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1896 bool postponed = false; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1897 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1898 RelocIterator iter(this, low_boundary); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1899 while(iter.next()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1900 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1901 switch (iter.type()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1902 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1903 case relocInfo::virtual_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1904 if (unloading_occurred) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1905 // If class unloading occurred we first iterate over all inline caches and |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1906 // clear ICs where the cached oop is referring to an unloaded klass or method. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1907 clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1908 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1909 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1910 postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1911 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1912 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1913 case relocInfo::opt_virtual_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1914 postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1915 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1916 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1917 case relocInfo::static_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1918 postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1919 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1920 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1921 case relocInfo::oop_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1922 if (!is_unloaded) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1923 // Unload check |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1924 oop_Relocation* r = iter.oop_reloc(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1925 // Traverse those oops directly embedded in the code. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1926 // Other oops (oop_index>0) are seen as part of scopes_oops. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1927 assert(1 == (r->oop_is_immediate()) + |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1928 (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1929 "oop must be found in exactly one place"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1930 if (r->oop_is_immediate() && r->oop_value() != NULL) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1931 if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1932 is_unloaded = true; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1933 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1934 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1935 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1936 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1937 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1938 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1939 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1940 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1941 if (is_unloaded) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1942 return postponed; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1943 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1944 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1945 // Scopes |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1946 for (oop* p = oops_begin(); p < oops_end(); p++) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1947 if (*p == Universe::non_oop_word()) continue; // skip non-oops |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1948 if (can_unload(is_alive, p, unloading_occurred)) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1949 is_unloaded = true; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1950 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1951 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1952 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1953 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1954 if (is_unloaded) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1955 return postponed; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1956 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1957 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1958 // Ensure that all metadata is still alive |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1959 verify_metadata_loaders(low_boundary, is_alive); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1960 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1961 return postponed; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1962 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1963 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1964 void nmethod::do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1965 ResourceMark rm; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1966 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1967 // Make sure the oop's ready to receive visitors |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1968 assert(!is_zombie(), |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1969 "should not call follow on zombie nmethod"); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1970 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1971 // If the method is not entrant then a JMP is plastered over the |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1972 // first few bytes. If an oop in the old code was there, that oop |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1973 // should not get GC'd. Skip the first few bytes of oops on |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1974 // not-entrant methods. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1975 address low_boundary = verified_entry_point(); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1976 if (is_not_entrant()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1977 low_boundary += NativeJump::instruction_size; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1978 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1979 // (See comment above.) |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1980 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1981 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1982 RelocIterator iter(this, low_boundary); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1983 while(iter.next()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1984 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1985 switch (iter.type()) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1986 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1987 case relocInfo::virtual_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1988 clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1989 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1990 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1991 case relocInfo::opt_virtual_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1992 clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1993 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1994 |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1995 case relocInfo::static_call_type: |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1996 clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this); |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1997 break; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1998 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
1999 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2000 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2001 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2002 #ifdef ASSERT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2003 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2004 class CheckClass : AllStatic { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2005 static BoolObjectClosure* _is_alive; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2006 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2007 // Check class_loader is alive for this bit of metadata. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2008 static void check_class(Metadata* md) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2009 Klass* klass = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2010 if (md->is_klass()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2011 klass = ((Klass*)md); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2012 } else if (md->is_method()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2013 klass = ((Method*)md)->method_holder(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2014 } else if (md->is_methodData()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2015 klass = ((MethodData*)md)->method()->method_holder(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2016 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2017 md->print(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2018 ShouldNotReachHere(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2019 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2020 assert(klass->is_loader_alive(_is_alive), "must be alive"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2021 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2022 public: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2023 static void do_check_class(BoolObjectClosure* is_alive, nmethod* nm) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2024 assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2025 _is_alive = is_alive; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2026 nm->metadata_do(check_class); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2027 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2028 }; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2029 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2030 // This is called during a safepoint so can use static data |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2031 BoolObjectClosure* CheckClass::_is_alive = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2032 #endif // ASSERT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2033 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2034 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2035 // Processing of oop references should have been sufficient to keep |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2036 // all strong references alive. Any weak references should have been |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2037 // cleared as well. Visit all the metadata and ensure that it's |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2038 // really alive. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2039 void nmethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2040 #ifdef ASSERT |
0 | 2041 RelocIterator iter(this, low_boundary); |
2042 while (iter.next()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2043 // static_stub_Relocations may have dangling references to |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2044 // Method*s so trim them out here. Otherwise it looks like |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2045 // compiled code is maintaining a link to dead metadata. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2046 address static_call_addr = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2047 if (iter.type() == relocInfo::opt_virtual_call_type) { |
20277
882004b9e7e1
8047362: Add a version of CompiledIC_at that doesn't create a new RelocIterator
stefank
parents:
20269
diff
changeset
|
2048 CompiledIC* cic = CompiledIC_at(&iter); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2049 if (!cic->is_call_to_interpreted()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2050 static_call_addr = iter.addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2051 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2052 } else if (iter.type() == relocInfo::static_call_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2053 CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2054 if (!csc->is_call_to_interpreted()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2055 static_call_addr = iter.addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2056 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2057 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2058 if (static_call_addr != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2059 RelocIterator sciter(this, low_boundary); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2060 while (sciter.next()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2061 if (sciter.type() == relocInfo::static_stub_type && |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2062 sciter.static_stub_reloc()->static_call() == static_call_addr) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2063 sciter.static_stub_reloc()->clear_inline_cache(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2064 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2065 } |
0 | 2066 } |
2067 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2068 // Check that the metadata embedded in the nmethod is alive |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2069 CheckClass::do_check_class(is_alive, this); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2070 #endif |
0 | 2071 } |
2072 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2073 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2074 // Iterate over metadata calling this function. Used by RedefineClasses |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2075 void nmethod::metadata_do(void f(Metadata*)) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2076 address low_boundary = verified_entry_point(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2077 if (is_not_entrant()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2078 low_boundary += NativeJump::instruction_size; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2079 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2080 // (See comment above.) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2081 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2082 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2083 // Visit all immediate references that are embedded in the instruction stream. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2084 RelocIterator iter(this, low_boundary); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2085 while (iter.next()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2086 if (iter.type() == relocInfo::metadata_type ) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2087 metadata_Relocation* r = iter.metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2088 // In this lmetadata, we must only follow those metadatas directly embedded in |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2089 // the code. Other metadatas (oop_index>0) are seen as part of |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2090 // the metadata section below. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2091 assert(1 == (r->metadata_is_immediate()) + |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2092 (r->metadata_addr() >= metadata_begin() && r->metadata_addr() < metadata_end()), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2093 "metadata must be found in exactly one place"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2094 if (r->metadata_is_immediate() && r->metadata_value() != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2095 Metadata* md = r->metadata_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2096 f(md); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2097 } |
10253
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2098 } else if (iter.type() == relocInfo::virtual_call_type) { |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2099 // Check compiledIC holders associated with this nmethod |
20277
882004b9e7e1
8047362: Add a version of CompiledIC_at that doesn't create a new RelocIterator
stefank
parents:
20269
diff
changeset
|
2100 CompiledIC *ic = CompiledIC_at(&iter); |
10253
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2101 if (ic->is_icholder_call()) { |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2102 CompiledICHolder* cichk = ic->cached_icholder(); |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2103 f(cichk->holder_method()); |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2104 f(cichk->holder_klass()); |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2105 } else { |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2106 Metadata* ic_oop = ic->cached_metadata(); |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2107 if (ic_oop != NULL) { |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2108 f(ic_oop); |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2109 } |
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2110 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2111 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2112 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2113 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2114 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2115 // Visit the metadata section |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2116 for (Metadata** p = metadata_begin(); p < metadata_end(); p++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2117 if (*p == Universe::non_oop_word() || *p == NULL) continue; // skip non-oops |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2118 Metadata* md = *p; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2119 f(md); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2120 } |
10253
4674e409a9e6
8014024: NPG: keep compiled ic methods from being deallocated in redefine classes
coleenp
parents:
10114
diff
changeset
|
2121 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2122 // Call function Method*, not embedded in these other places. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2123 if (_method != NULL) f(_method); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2124 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2125 |
12080 | 2126 void nmethod::oops_do(OopClosure* f, bool allow_zombie) { |
0 | 2127 // make sure the oops ready to receive visitors |
12080 | 2128 assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod"); |
2129 assert(!is_unloaded(), "should not call follow on unloaded nmethod"); | |
0 | 2130 |
2131 // If the method is not entrant or zombie then a JMP is plastered over the | |
2132 // first few bytes. If an oop in the old code was there, that oop | |
2133 // should not get GC'd. Skip the first few bytes of oops on | |
2134 // not-entrant methods. | |
2135 address low_boundary = verified_entry_point(); | |
2136 if (is_not_entrant()) { | |
2137 low_boundary += NativeJump::instruction_size; | |
2138 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. | |
2139 // (See comment above.) | |
2140 } | |
2141 | |
2142 RelocIterator iter(this, low_boundary); | |
941 | 2143 |
0 | 2144 while (iter.next()) { |
2145 if (iter.type() == relocInfo::oop_type ) { | |
2146 oop_Relocation* r = iter.oop_reloc(); | |
2147 // In this loop, we must only follow those oops directly embedded in | |
2148 // the code. Other oops (oop_index>0) are seen as part of scopes_oops. | |
941 | 2149 assert(1 == (r->oop_is_immediate()) + |
2150 (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), | |
2151 "oop must be found in exactly one place"); | |
0 | 2152 if (r->oop_is_immediate() && r->oop_value() != NULL) { |
2153 f->do_oop(r->oop_addr()); | |
2154 } | |
2155 } | |
2156 } | |
2157 | |
2158 // Scopes | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2159 // This includes oop constants not inlined in the code stream. |
0 | 2160 for (oop* p = oops_begin(); p < oops_end(); p++) { |
2161 if (*p == Universe::non_oop_word()) continue; // skip non-oops | |
2162 f->do_oop(p); | |
2163 } | |
2164 } | |
2165 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2166 #define NMETHOD_SENTINEL ((nmethod*)badAddress) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2167 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2168 nmethod* volatile nmethod::_oops_do_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2169 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2170 // An nmethod is "marked" if its _mark_link is set non-null. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2171 // Even if it is the end of the linked list, it will have a non-null link value, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2172 // as long as it is on the list. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2173 // This code must be MP safe, because it is used from parallel GC passes. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2174 bool nmethod::test_set_oops_do_mark() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2175 assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2176 nmethod* observed_mark_link = _oops_do_mark_link; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2177 if (observed_mark_link == NULL) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2178 // Claim this nmethod for this thread to mark. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2179 observed_mark_link = (nmethod*) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2180 Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_link, NULL); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2181 if (observed_mark_link == NULL) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2182 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2183 // Atomically append this nmethod (now claimed) to the head of the list: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2184 nmethod* observed_mark_nmethods = _oops_do_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2185 for (;;) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2186 nmethod* required_mark_nmethods = observed_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2187 _oops_do_mark_link = required_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2188 observed_mark_nmethods = (nmethod*) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2189 Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2190 if (observed_mark_nmethods == required_mark_nmethods) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2191 break; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2192 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2193 // Mark was clear when we first saw this guy. |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
2194 NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark")); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2195 return false; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2196 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2197 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2198 // On fall through, another racing thread marked this nmethod before we did. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2199 return true; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2200 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2201 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2202 void nmethod::oops_do_marking_prologue() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2203 NOT_PRODUCT(if (TraceScavenge) tty->print_cr("[oops_do_marking_prologue")); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2204 assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2205 // We use cmpxchg_ptr instead of regular assignment here because the user |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2206 // may fork a bunch of threads, and we need them all to see the same state. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2207 void* observed = Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, NULL); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2208 guarantee(observed == NULL, "no races in this sequential code"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2209 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2210 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2211 void nmethod::oops_do_marking_epilogue() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2212 assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2213 nmethod* cur = _oops_do_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2214 while (cur != NMETHOD_SENTINEL) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2215 assert(cur != NULL, "not NULL-terminated"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2216 nmethod* next = cur->_oops_do_mark_link; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2217 cur->_oops_do_mark_link = NULL; |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2218 cur->verify_oop_relocations(); |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
2219 NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark")); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2220 cur = next; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2221 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2222 void* required = _oops_do_mark_nmethods; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2223 void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2224 guarantee(observed == required, "no races in this sequential code"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2225 NOT_PRODUCT(if (TraceScavenge) tty->print_cr("oops_do_marking_epilogue]")); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2226 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2227 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2228 class DetectScavengeRoot: public OopClosure { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2229 bool _detected_scavenge_root; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2230 public: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2231 DetectScavengeRoot() : _detected_scavenge_root(false) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2232 { NOT_PRODUCT(_print_nm = NULL); } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2233 bool detected_scavenge_root() { return _detected_scavenge_root; } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2234 virtual void do_oop(oop* p) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2235 if ((*p) != NULL && (*p)->is_scavengable()) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2236 NOT_PRODUCT(maybe_print(p)); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2237 _detected_scavenge_root = true; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2238 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2239 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2240 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2241 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2242 #ifndef PRODUCT |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2243 nmethod* _print_nm; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2244 void maybe_print(oop* p) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2245 if (_print_nm == NULL) return; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2246 if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root"); |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2405
diff
changeset
|
2247 tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")", |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2248 _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm), |
12316
190899198332
7195622: CheckUnhandledOops has limited usefulness now
hseigel
parents:
12175
diff
changeset
|
2249 (void *)(*p), (intptr_t)p); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2250 (*p)->print(); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2251 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2252 #endif //PRODUCT |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2253 }; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2254 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2255 bool nmethod::detect_scavenge_root_oops() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2256 DetectScavengeRoot detect_scavenge_root; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2257 NOT_PRODUCT(if (TraceScavenge) detect_scavenge_root._print_nm = this); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2258 oops_do(&detect_scavenge_root); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2259 return detect_scavenge_root.detected_scavenge_root(); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2260 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2261 |
0 | 2262 // Method that knows how to preserve outgoing arguments at call. This method must be |
2263 // called with a frame corresponding to a Java invoke | |
2264 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { | |
1692 | 2265 #ifndef SHARK |
0 | 2266 if (!method()->is_native()) { |
2267 SimpleScopeDesc ssd(this, fr.pc()); | |
2142 | 2268 Bytecode_invoke call(ssd.method(), ssd.bci()); |
10390 | 2269 bool has_receiver = call.has_receiver(); |
2270 bool has_appendix = call.has_appendix(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
2271 Symbol* signature = call.signature(); |
10390 | 2272 fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f); |
0 | 2273 } |
1692 | 2274 #endif // !SHARK |
0 | 2275 } |
2276 | |
2277 | |
2278 oop nmethod::embeddedOop_at(u_char* p) { | |
2349
4cd9add59b1e
7024866: # assert(limit == NULL || limit <= nm->code_end()) failed: in bounds
never
parents:
2321
diff
changeset
|
2279 RelocIterator iter(this, p, p + 1); |
0 | 2280 while (iter.next()) |
2281 if (iter.type() == relocInfo::oop_type) { | |
2282 return iter.oop_reloc()->oop_value(); | |
2283 } | |
2284 return NULL; | |
2285 } | |
2286 | |
2287 | |
2288 inline bool includes(void* p, void* from, void* to) { | |
2289 return from <= p && p < to; | |
2290 } | |
2291 | |
2292 | |
2293 void nmethod::copy_scopes_pcs(PcDesc* pcs, int count) { | |
2294 assert(count >= 2, "must be sentinel values, at least"); | |
2295 | |
2296 #ifdef ASSERT | |
2297 // must be sorted and unique; we do a binary search in find_pc_desc() | |
2298 int prev_offset = pcs[0].pc_offset(); | |
2299 assert(prev_offset == PcDesc::lower_offset_limit, | |
2300 "must start with a sentinel"); | |
2301 for (int i = 1; i < count; i++) { | |
2302 int this_offset = pcs[i].pc_offset(); | |
2303 assert(this_offset > prev_offset, "offsets must be sorted"); | |
2304 prev_offset = this_offset; | |
2305 } | |
2306 assert(prev_offset == PcDesc::upper_offset_limit, | |
2307 "must end with a sentinel"); | |
2308 #endif //ASSERT | |
2309 | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2310 // Search for MethodHandle invokes and tag the nmethod. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2311 for (int i = 0; i < count; i++) { |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2312 if (pcs[i].is_method_handle_invoke()) { |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2313 set_has_method_handle_invokes(true); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2314 break; |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2315 } |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2316 } |
2083
7d9caaedafce
6990933: assert(sender_cb) failed: sanity in frame::sender_for_interpreter_frame
twisti
parents:
1972
diff
changeset
|
2317 assert(has_method_handle_invokes() == (_deoptimize_mh_offset != -1), "must have deopt mh handler"); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2318 |
0 | 2319 int size = count * sizeof(PcDesc); |
2320 assert(scopes_pcs_size() >= size, "oob"); | |
2321 memcpy(scopes_pcs_begin(), pcs, size); | |
2322 | |
2323 // Adjust the final sentinel downward. | |
2324 PcDesc* last_pc = &scopes_pcs_begin()[count-1]; | |
2325 assert(last_pc->pc_offset() == PcDesc::upper_offset_limit, "sanity"); | |
1748 | 2326 last_pc->set_pc_offset(content_size() + 1); |
0 | 2327 for (; last_pc + 1 < scopes_pcs_end(); last_pc += 1) { |
2328 // Fill any rounding gaps with copies of the last record. | |
2329 last_pc[1] = last_pc[0]; | |
2330 } | |
2331 // The following assert could fail if sizeof(PcDesc) is not | |
2332 // an integral multiple of oopSize (the rounding term). | |
2333 // If it fails, change the logic to always allocate a multiple | |
2334 // of sizeof(PcDesc), and fill unused words with copies of *last_pc. | |
2335 assert(last_pc + 1 == scopes_pcs_end(), "must match exactly"); | |
2336 } | |
2337 | |
2338 void nmethod::copy_scopes_data(u_char* buffer, int size) { | |
2339 assert(scopes_data_size() >= size, "oob"); | |
2340 memcpy(scopes_data_begin(), buffer, size); | |
2341 } | |
2342 | |
2343 | |
2344 #ifdef ASSERT | |
2345 static PcDesc* linear_search(nmethod* nm, int pc_offset, bool approximate) { | |
2346 PcDesc* lower = nm->scopes_pcs_begin(); | |
2347 PcDesc* upper = nm->scopes_pcs_end(); | |
2348 lower += 1; // exclude initial sentinel | |
2349 PcDesc* res = NULL; | |
2350 for (PcDesc* p = lower; p < upper; p++) { | |
2351 NOT_PRODUCT(--nmethod_stats.pc_desc_tests); // don't count this call to match_desc | |
2352 if (match_desc(p, pc_offset, approximate)) { | |
2353 if (res == NULL) | |
2354 res = p; | |
2355 else | |
2356 res = (PcDesc*) badAddress; | |
2357 } | |
2358 } | |
2359 return res; | |
2360 } | |
2361 #endif | |
2362 | |
2363 | |
2364 // Finds a PcDesc with real-pc equal to "pc" | |
2365 PcDesc* nmethod::find_pc_desc_internal(address pc, bool approximate) { | |
1748 | 2366 address base_address = code_begin(); |
0 | 2367 if ((pc < base_address) || |
2368 (pc - base_address) >= (ptrdiff_t) PcDesc::upper_offset_limit) { | |
2369 return NULL; // PC is wildly out of range | |
2370 } | |
2371 int pc_offset = (int) (pc - base_address); | |
2372 | |
2373 // Check the PcDesc cache if it contains the desired PcDesc | |
2374 // (This as an almost 100% hit rate.) | |
2375 PcDesc* res = _pc_desc_cache.find_pc_desc(pc_offset, approximate); | |
2376 if (res != NULL) { | |
2377 assert(res == linear_search(this, pc_offset, approximate), "cache ok"); | |
2378 return res; | |
2379 } | |
2380 | |
2381 // Fallback algorithm: quasi-linear search for the PcDesc | |
2382 // Find the last pc_offset less than the given offset. | |
2383 // The successor must be the required match, if there is a match at all. | |
2384 // (Use a fixed radix to avoid expensive affine pointer arithmetic.) | |
2385 PcDesc* lower = scopes_pcs_begin(); | |
2386 PcDesc* upper = scopes_pcs_end(); | |
2387 upper -= 1; // exclude final sentinel | |
2388 if (lower >= upper) return NULL; // native method; no PcDescs at all | |
2389 | |
2390 #define assert_LU_OK \ | |
2391 /* invariant on lower..upper during the following search: */ \ | |
2392 assert(lower->pc_offset() < pc_offset, "sanity"); \ | |
2393 assert(upper->pc_offset() >= pc_offset, "sanity") | |
2394 assert_LU_OK; | |
2395 | |
2396 // Use the last successful return as a split point. | |
2397 PcDesc* mid = _pc_desc_cache.last_pc_desc(); | |
2398 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); | |
2399 if (mid->pc_offset() < pc_offset) { | |
2400 lower = mid; | |
2401 } else { | |
2402 upper = mid; | |
2403 } | |
2404 | |
2405 // Take giant steps at first (4096, then 256, then 16, then 1) | |
2406 const int LOG2_RADIX = 4 /*smaller steps in debug mode:*/ debug_only(-1); | |
2407 const int RADIX = (1 << LOG2_RADIX); | |
2408 for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) { | |
2409 while ((mid = lower + step) < upper) { | |
2410 assert_LU_OK; | |
2411 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); | |
2412 if (mid->pc_offset() < pc_offset) { | |
2413 lower = mid; | |
2414 } else { | |
2415 upper = mid; | |
2416 break; | |
2417 } | |
2418 } | |
2419 assert_LU_OK; | |
2420 } | |
2421 | |
2422 // Sneak up on the value with a linear search of length ~16. | |
2423 while (true) { | |
2424 assert_LU_OK; | |
2425 mid = lower + 1; | |
2426 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); | |
2427 if (mid->pc_offset() < pc_offset) { | |
2428 lower = mid; | |
2429 } else { | |
2430 upper = mid; | |
2431 break; | |
2432 } | |
2433 } | |
2434 #undef assert_LU_OK | |
2435 | |
2436 if (match_desc(upper, pc_offset, approximate)) { | |
2437 assert(upper == linear_search(this, pc_offset, approximate), "search ok"); | |
2438 _pc_desc_cache.add_pc_desc(upper); | |
2439 return upper; | |
2440 } else { | |
2441 assert(NULL == linear_search(this, pc_offset, approximate), "search ok"); | |
2442 return NULL; | |
2443 } | |
2444 } | |
2445 | |
2446 | |
2447 bool nmethod::check_all_dependencies() { | |
2448 bool found_check = false; | |
2449 // wholesale check of all dependencies | |
2450 for (Dependencies::DepStream deps(this); deps.next(); ) { | |
2451 if (deps.check_dependency() != NULL) { | |
2452 found_check = true; | |
2453 NOT_DEBUG(break); | |
2454 } | |
2455 } | |
2456 return found_check; // tell caller if we found anything | |
2457 } | |
2458 | |
2459 bool nmethod::check_dependency_on(DepChange& changes) { | |
2460 // What has happened: | |
2461 // 1) a new class dependee has been added | |
2462 // 2) dependee and all its super classes have been marked | |
2463 bool found_check = false; // set true if we are upset | |
2464 for (Dependencies::DepStream deps(this); deps.next(); ) { | |
2465 // Evaluate only relevant dependencies. | |
2466 if (deps.spot_check_dependency_at(changes) != NULL) { | |
2467 found_check = true; | |
2468 NOT_DEBUG(break); | |
2469 } | |
2470 } | |
2471 return found_check; | |
2472 } | |
2473 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2474 bool nmethod::is_evol_dependent_on(Klass* dependee) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2475 InstanceKlass *dependee_ik = InstanceKlass::cast(dependee); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2476 Array<Method*>* dependee_methods = dependee_ik->methods(); |
0 | 2477 for (Dependencies::DepStream deps(this); deps.next(); ) { |
2478 if (deps.type() == Dependencies::evol_method) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2479 Method* method = deps.method_argument(0); |
0 | 2480 for (int j = 0; j < dependee_methods->length(); j++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2481 if (dependee_methods->at(j) == method) { |
0 | 2482 // RC_TRACE macro has an embedded ResourceMark |
2483 RC_TRACE(0x01000000, | |
2484 ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2485 _method->method_holder()->external_name(), |
0 | 2486 _method->name()->as_C_string(), |
2487 _method->signature()->as_C_string(), compile_id(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2488 method->method_holder()->external_name(), |
0 | 2489 method->name()->as_C_string(), |
2490 method->signature()->as_C_string())); | |
2491 if (TraceDependencies || LogCompilation) | |
2492 deps.log_dependency(dependee); | |
2493 return true; | |
2494 } | |
2495 } | |
2496 } | |
2497 } | |
2498 return false; | |
2499 } | |
2500 | |
2501 // Called from mark_for_deoptimization, when dependee is invalidated. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2502 bool nmethod::is_dependent_on_method(Method* dependee) { |
0 | 2503 for (Dependencies::DepStream deps(this); deps.next(); ) { |
2504 if (deps.type() != Dependencies::evol_method) | |
2505 continue; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2506 Method* method = deps.method_argument(0); |
0 | 2507 if (method == dependee) return true; |
2508 } | |
2509 return false; | |
2510 } | |
2511 | |
2512 | |
2513 bool nmethod::is_patchable_at(address instr_addr) { | |
1748 | 2514 assert(insts_contains(instr_addr), "wrong nmethod used"); |
0 | 2515 if (is_zombie()) { |
2516 // a zombie may never be patched | |
2517 return false; | |
2518 } | |
2519 return true; | |
2520 } | |
2521 | |
2522 | |
2523 address nmethod::continuation_for_implicit_exception(address pc) { | |
2524 // Exception happened outside inline-cache check code => we are inside | |
2525 // an active nmethod => use cpc to determine a return address | |
1748 | 2526 int exception_offset = pc - code_begin(); |
0 | 2527 int cont_offset = ImplicitExceptionTable(this).at( exception_offset ); |
2528 #ifdef ASSERT | |
2529 if (cont_offset == 0) { | |
2530 Thread* thread = ThreadLocalStorage::get_thread_slow(); | |
2531 ResetNoHandleMark rnm; // Might be called from LEAF/QUICK ENTRY | |
2532 HandleMark hm(thread); | |
2533 ResourceMark rm(thread); | |
2534 CodeBlob* cb = CodeCache::find_blob(pc); | |
2535 assert(cb != NULL && cb == this, ""); | |
2536 tty->print_cr("implicit exception happened at " INTPTR_FORMAT, pc); | |
2537 print(); | |
2538 method()->print_codes(); | |
2539 print_code(); | |
2540 print_pcs(); | |
2541 } | |
2542 #endif | |
1250 | 2543 if (cont_offset == 0) { |
2544 // Let the normal error handling report the exception | |
2545 return NULL; | |
2546 } | |
1748 | 2547 return code_begin() + cont_offset; |
0 | 2548 } |
2549 | |
2550 | |
2551 | |
2552 void nmethod_init() { | |
2553 // make sure you didn't forget to adjust the filler fields | |
2554 assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word"); | |
2555 } | |
2556 | |
2557 | |
2558 //------------------------------------------------------------------------------------------- | |
2559 | |
2560 | |
2561 // QQQ might we make this work from a frame?? | |
2562 nmethodLocker::nmethodLocker(address pc) { | |
2563 CodeBlob* cb = CodeCache::find_blob(pc); | |
2564 guarantee(cb != NULL && cb->is_nmethod(), "bad pc for a nmethod found"); | |
2565 _nm = (nmethod*)cb; | |
2566 lock_nmethod(_nm); | |
2567 } | |
2568 | |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
2569 // Only JvmtiDeferredEvent::compiled_method_unload_event() |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
2570 // should pass zombie_ok == true. |
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
2571 void nmethodLocker::lock_nmethod(nmethod* nm, bool zombie_ok) { |
0 | 2572 if (nm == NULL) return; |
2573 Atomic::inc(&nm->_lock_count); | |
2342
46a56fac55c7
7024970: 2/3 assert(ServiceThread::is_service_thread(Thread::current())) failed: Service thread must post enqueue
dcubed
parents:
2321
diff
changeset
|
2574 guarantee(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method"); |
0 | 2575 } |
2576 | |
2577 void nmethodLocker::unlock_nmethod(nmethod* nm) { | |
2578 if (nm == NULL) return; | |
2579 Atomic::dec(&nm->_lock_count); | |
2580 guarantee(nm->_lock_count >= 0, "unmatched nmethod lock/unlock"); | |
2581 } | |
2582 | |
1204 | 2583 |
2584 // ----------------------------------------------------------------------------- | |
2585 // nmethod::get_deopt_original_pc | |
2586 // | |
2587 // Return the original PC for the given PC if: | |
2588 // (a) the given PC belongs to a nmethod and | |
2589 // (b) it is a deopt PC | |
2590 address nmethod::get_deopt_original_pc(const frame* fr) { | |
2591 if (fr->cb() == NULL) return NULL; | |
2592 | |
2593 nmethod* nm = fr->cb()->as_nmethod_or_null(); | |
2594 if (nm != NULL && nm->is_deopt_pc(fr->pc())) | |
2595 return nm->get_original_pc(fr); | |
2596 | |
2597 return NULL; | |
0 | 2598 } |
2599 | |
2600 | |
2601 // ----------------------------------------------------------------------------- | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2602 // MethodHandle |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2603 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2604 bool nmethod::is_method_handle_return(address return_pc) { |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2605 if (!has_method_handle_invokes()) return false; |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2606 PcDesc* pd = pc_desc_at(return_pc); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2607 if (pd == NULL) |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2608 return false; |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2609 return pd->is_method_handle_invoke(); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2610 } |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2611 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2612 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1109
diff
changeset
|
2613 // ----------------------------------------------------------------------------- |
0 | 2614 // Verification |
2615 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2616 class VerifyOopsClosure: public OopClosure { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2617 nmethod* _nm; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2618 bool _ok; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2619 public: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2620 VerifyOopsClosure(nmethod* nm) : _nm(nm), _ok(true) { } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2621 bool ok() { return _ok; } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2622 virtual void do_oop(oop* p) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2623 if ((*p) == NULL || (*p)->is_oop()) return; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2624 if (_ok) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2625 _nm->print_nmethod(true); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2626 _ok = false; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2627 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2628 tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)", |
12316
190899198332
7195622: CheckUnhandledOops has limited usefulness now
hseigel
parents:
12175
diff
changeset
|
2629 (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2630 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2631 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2632 }; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2633 |
0 | 2634 void nmethod::verify() { |
2635 | |
2636 // Hmm. OSR methods can be deopted but not marked as zombie or not_entrant | |
2637 // seems odd. | |
2638 | |
2639 if( is_zombie() || is_not_entrant() ) | |
2640 return; | |
2641 | |
2642 // Make sure all the entry points are correctly aligned for patching. | |
2643 NativeJump::check_verified_entry_alignment(entry_point(), verified_entry_point()); | |
2644 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2645 // assert(method()->is_oop(), "must be valid"); |
0 | 2646 |
2647 ResourceMark rm; | |
2648 | |
2649 if (!CodeCache::contains(this)) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
2650 fatal(err_msg("nmethod at " INTPTR_FORMAT " not in zone", this)); |
0 | 2651 } |
2652 | |
2653 if(is_native_method() ) | |
2654 return; | |
2655 | |
2656 nmethod* nm = CodeCache::find_nmethod(verified_entry_point()); | |
2657 if (nm != this) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
2658 fatal(err_msg("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
2659 this)); |
0 | 2660 } |
2661 | |
2662 for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { | |
2663 if (! p->verify(this)) { | |
2664 tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", this); | |
2665 } | |
2666 } | |
2667 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2668 VerifyOopsClosure voc(this); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2669 oops_do(&voc); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2670 assert(voc.ok(), "embedded oops must be OK"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2671 verify_scavenge_root_oops(); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2672 |
0 | 2673 verify_scopes(); |
2674 } | |
2675 | |
2676 | |
2677 void nmethod::verify_interrupt_point(address call_site) { | |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2678 // Verify IC only when nmethod installation is finished. |
13441 | 2679 bool is_installed = (method()->code() == this) // nmethod is in state 'in_use' and installed |
2680 || !this->is_in_use(); // nmethod is installed, but not in 'in_use' state | |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2681 if (is_installed) { |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2682 Thread *cur = Thread::current(); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2683 if (CompiledIC_lock->owner() == cur || |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2684 ((cur->is_VM_thread() || cur->is_ConcurrentGC_thread()) && |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2685 SafepointSynchronize::is_at_safepoint())) { |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2686 CompiledIC_at(this, call_site); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2687 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2688 } else { |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2689 MutexLocker ml_verify (CompiledIC_lock); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2690 CompiledIC_at(this, call_site); |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2691 } |
0 | 2692 } |
13071
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2693 |
e2509677809c
8023037: Race between ciEnv::register_method and nmethod::make_not_entrant_or_zombie
vlivanov
parents:
12334
diff
changeset
|
2694 PcDesc* pd = pc_desc_at(nativeCall_at(call_site)->return_address()); |
0 | 2695 assert(pd != NULL, "PcDesc must exist"); |
2696 for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(), | |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
2697 pd->obj_decode_offset(), pd->should_reexecute(), |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
2698 pd->return_oop()); |
0 | 2699 !sd->is_top(); sd = sd->sender()) { |
2700 sd->verify(); | |
2701 } | |
2702 } | |
2703 | |
2704 void nmethod::verify_scopes() { | |
2705 if( !method() ) return; // Runtime stubs have no scope | |
2706 if (method()->is_native()) return; // Ignore stub methods. | |
2707 // iterate through all interrupt point | |
2708 // and verify the debug information is valid. | |
2709 RelocIterator iter((nmethod*)this); | |
2710 while (iter.next()) { | |
2711 address stub = NULL; | |
2712 switch (iter.type()) { | |
2713 case relocInfo::virtual_call_type: | |
2714 verify_interrupt_point(iter.addr()); | |
2715 break; | |
2716 case relocInfo::opt_virtual_call_type: | |
2717 stub = iter.opt_virtual_call_reloc()->static_stub(); | |
2718 verify_interrupt_point(iter.addr()); | |
2719 break; | |
2720 case relocInfo::static_call_type: | |
2721 stub = iter.static_call_reloc()->static_stub(); | |
2722 //verify_interrupt_point(iter.addr()); | |
2723 break; | |
2724 case relocInfo::runtime_call_type: | |
2725 address destination = iter.reloc()->value(); | |
2726 // Right now there is no way to find out which entries support | |
2727 // an interrupt point. It would be nice if we had this | |
2728 // information in a table. | |
2729 break; | |
2730 } | |
2731 assert(stub == NULL || stub_contains(stub), "static call stub outside stub section"); | |
2732 } | |
2733 } | |
2734 | |
2735 | |
2736 // ----------------------------------------------------------------------------- | |
2737 // Non-product code | |
2738 #ifndef PRODUCT | |
2739 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2740 class DebugScavengeRoot: public OopClosure { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2741 nmethod* _nm; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2742 bool _ok; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2743 public: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2744 DebugScavengeRoot(nmethod* nm) : _nm(nm), _ok(true) { } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2745 bool ok() { return _ok; } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2746 virtual void do_oop(oop* p) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2747 if ((*p) == NULL || !(*p)->is_scavengable()) return; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2748 if (_ok) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2749 _nm->print_nmethod(true); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2750 _ok = false; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2751 } |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2405
diff
changeset
|
2752 tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)", |
12316
190899198332
7195622: CheckUnhandledOops has limited usefulness now
hseigel
parents:
12175
diff
changeset
|
2753 (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2754 (*p)->print(); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2755 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2756 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2757 }; |
0 | 2758 |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2759 void nmethod::verify_scavenge_root_oops() { |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2760 if (UseG1GC) { |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2761 return; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2762 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20277
diff
changeset
|
2763 |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2764 if (!on_scavenge_root_list()) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2765 // Actually look inside, to verify the claim that it's clean. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2766 DebugScavengeRoot debug_scavenge_root(this); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2767 oops_do(&debug_scavenge_root); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2768 if (!debug_scavenge_root.ok()) |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2405
diff
changeset
|
2769 fatal("found an unadvertised bad scavengable oop in the code cache"); |
0 | 2770 } |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2771 assert(scavenge_root_not_marked(), ""); |
0 | 2772 } |
2773 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2774 #endif // PRODUCT |
0 | 2775 |
2776 // Printing operations | |
2777 | |
2778 void nmethod::print() const { | |
2779 ResourceMark rm; | |
2780 ttyLocker ttyl; // keep the following output all in one block | |
2781 | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
2782 tty->print("Compiled method "); |
0 | 2783 |
2784 if (is_compiled_by_c1()) { | |
2785 tty->print("(c1) "); | |
2786 } else if (is_compiled_by_c2()) { | |
2787 tty->print("(c2) "); | |
1692 | 2788 } else if (is_compiled_by_shark()) { |
2789 tty->print("(shark) "); | |
0 | 2790 } else { |
2791 tty->print("(nm) "); | |
2792 } | |
2793 | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
2794 print_on(tty, NULL); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
2795 |
0 | 2796 if (WizardMode) { |
2797 tty->print("((nmethod*) "INTPTR_FORMAT ") ", this); | |
2798 tty->print(" for method " INTPTR_FORMAT , (address)method()); | |
2799 tty->print(" { "); | |
2800 if (is_in_use()) tty->print("in_use "); | |
2801 if (is_not_entrant()) tty->print("not_entrant "); | |
2802 if (is_zombie()) tty->print("zombie "); | |
2803 if (is_unloaded()) tty->print("unloaded "); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
931
diff
changeset
|
2804 if (on_scavenge_root_list()) tty->print("scavenge_root "); |
0 | 2805 tty->print_cr("}:"); |
2806 } | |
2807 if (size () > 0) tty->print_cr(" total in heap [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2808 (address)this, | |
2809 (address)this + size(), | |
2810 size()); | |
2811 if (relocation_size () > 0) tty->print_cr(" relocation [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2812 relocation_begin(), | |
2813 relocation_end(), | |
2814 relocation_size()); | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
2815 if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
2816 consts_begin(), |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
2817 consts_end(), |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
2818 consts_size()); |
1748 | 2819 if (insts_size () > 0) tty->print_cr(" main code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
2820 insts_begin(), | |
2821 insts_end(), | |
2822 insts_size()); | |
0 | 2823 if (stub_size () > 0) tty->print_cr(" stub code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
2824 stub_begin(), | |
2825 stub_end(), | |
2826 stub_size()); | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
2827 if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
2828 oops_begin(), |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
2829 oops_end(), |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1538
diff
changeset
|
2830 oops_size()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2831 if (metadata_size () > 0) tty->print_cr(" metadata [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2832 metadata_begin(), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2833 metadata_end(), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2834 metadata_size()); |
0 | 2835 if (scopes_data_size () > 0) tty->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", |
2836 scopes_data_begin(), | |
2837 scopes_data_end(), | |
2838 scopes_data_size()); | |
2839 if (scopes_pcs_size () > 0) tty->print_cr(" scopes pcs [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2840 scopes_pcs_begin(), | |
2841 scopes_pcs_end(), | |
2842 scopes_pcs_size()); | |
2843 if (dependencies_size () > 0) tty->print_cr(" dependencies [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2844 dependencies_begin(), | |
2845 dependencies_end(), | |
2846 dependencies_size()); | |
2847 if (handler_table_size() > 0) tty->print_cr(" handler table [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2848 handler_table_begin(), | |
2849 handler_table_end(), | |
2850 handler_table_size()); | |
2851 if (nul_chk_table_size() > 0) tty->print_cr(" nul chk table [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", | |
2852 nul_chk_table_begin(), | |
2853 nul_chk_table_end(), | |
2854 nul_chk_table_size()); | |
2855 } | |
2856 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2857 void nmethod::print_code() { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2858 HandleMark hm; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2859 ResourceMark m; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2860 Disassembler::decode(this); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2861 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2862 |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2863 |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2864 #ifndef PRODUCT |
0 | 2865 |
2866 void nmethod::print_scopes() { | |
2867 // Find the first pc desc for all scopes in the code and print it. | |
2868 ResourceMark rm; | |
2869 for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { | |
2870 if (p->scope_decode_offset() == DebugInformationRecorder::serialized_null) | |
2871 continue; | |
2872 | |
2873 ScopeDesc* sd = scope_desc_at(p->real_pc(this)); | |
2874 sd->print_on(tty, p); | |
2875 } | |
2876 } | |
2877 | |
2878 void nmethod::print_dependencies() { | |
2879 ResourceMark rm; | |
2880 ttyLocker ttyl; // keep the following output all in one block | |
2881 tty->print_cr("Dependencies:"); | |
2882 for (Dependencies::DepStream deps(this); deps.next(); ) { | |
2883 deps.print_dependency(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2884 Klass* ctxk = deps.context_type(); |
0 | 2885 if (ctxk != NULL) { |
6983 | 2886 if (ctxk->oop_is_instance() && ((InstanceKlass*)ctxk)->is_dependent_nmethod(this)) { |
2887 tty->print_cr(" [nmethod<=klass]%s", ctxk->external_name()); | |
0 | 2888 } |
2889 } | |
2890 deps.log_dependency(); // put it into the xml log also | |
2891 } | |
2892 } | |
2893 | |
2894 | |
2895 void nmethod::print_relocations() { | |
2896 ResourceMark m; // in case methods get printed via the debugger | |
2897 tty->print_cr("relocations:"); | |
2898 RelocIterator iter(this); | |
2899 iter.print(); | |
2900 if (UseRelocIndex) { | |
2901 jint* index_end = (jint*)relocation_end() - 1; | |
2902 jint index_size = *index_end; | |
2903 jint* index_start = (jint*)( (address)index_end - index_size ); | |
2904 tty->print_cr(" index @" INTPTR_FORMAT ": index_size=%d", index_start, index_size); | |
2905 if (index_size > 0) { | |
2906 jint* ip; | |
2907 for (ip = index_start; ip+2 <= index_end; ip += 2) | |
2908 tty->print_cr(" (%d %d) addr=" INTPTR_FORMAT " @" INTPTR_FORMAT, | |
2909 ip[0], | |
2910 ip[1], | |
2911 header_end()+ip[0], | |
2912 relocation_begin()-1+ip[1]); | |
2913 for (; ip < index_end; ip++) | |
2914 tty->print_cr(" (%d ?)", ip[0]); | |
10973
ef57c43512d6
8014431: cleanup warnings indicated by the -Wunused-value compiler option on linux
ccheung
parents:
10390
diff
changeset
|
2915 tty->print_cr(" @" INTPTR_FORMAT ": index_size=%d", ip, *ip); |
ef57c43512d6
8014431: cleanup warnings indicated by the -Wunused-value compiler option on linux
ccheung
parents:
10390
diff
changeset
|
2916 ip++; |
0 | 2917 tty->print_cr("reloc_end @" INTPTR_FORMAT ":", ip); |
2918 } | |
2919 } | |
2920 } | |
2921 | |
2922 | |
2923 void nmethod::print_pcs() { | |
2924 ResourceMark m; // in case methods get printed via debugger | |
2925 tty->print_cr("pc-bytecode offsets:"); | |
2926 for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { | |
2927 p->print(this); | |
2928 } | |
2929 } | |
2930 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
2931 #endif // PRODUCT |
0 | 2932 |
2933 const char* nmethod::reloc_string_for(u_char* begin, u_char* end) { | |
2934 RelocIterator iter(this, begin, end); | |
2935 bool have_one = false; | |
2936 while (iter.next()) { | |
2937 have_one = true; | |
2938 switch (iter.type()) { | |
2939 case relocInfo::none: return "no_reloc"; | |
2940 case relocInfo::oop_type: { | |
2941 stringStream st; | |
2942 oop_Relocation* r = iter.oop_reloc(); | |
2943 oop obj = r->oop_value(); | |
2944 st.print("oop("); | |
2945 if (obj == NULL) st.print("NULL"); | |
2946 else obj->print_value_on(&st); | |
2947 st.print(")"); | |
2948 return st.as_string(); | |
2949 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2950 case relocInfo::metadata_type: { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2951 stringStream st; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2952 metadata_Relocation* r = iter.metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2953 Metadata* obj = r->metadata_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2954 st.print("metadata("); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2955 if (obj == NULL) st.print("NULL"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2956 else obj->print_value_on(&st); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2957 st.print(")"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2958 return st.as_string(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2959 } |
0 | 2960 case relocInfo::virtual_call_type: return "virtual_call"; |
2961 case relocInfo::opt_virtual_call_type: return "optimized virtual_call"; | |
2962 case relocInfo::static_call_type: return "static_call"; | |
2963 case relocInfo::static_stub_type: return "static_stub"; | |
2964 case relocInfo::runtime_call_type: return "runtime_call"; | |
2965 case relocInfo::external_word_type: return "external_word"; | |
2966 case relocInfo::internal_word_type: return "internal_word"; | |
2967 case relocInfo::section_word_type: return "section_word"; | |
2968 case relocInfo::poll_type: return "poll"; | |
2969 case relocInfo::poll_return_type: return "poll_return"; | |
2970 case relocInfo::type_mask: return "type_bit_mask"; | |
2971 } | |
2972 } | |
2973 return have_one ? "other" : NULL; | |
2974 } | |
2975 | |
2976 // Return a the last scope in (begin..end] | |
2977 ScopeDesc* nmethod::scope_desc_in(address begin, address end) { | |
2978 PcDesc* p = pc_desc_near(begin+1); | |
2979 if (p != NULL && p->real_pc(this) <= end) { | |
2980 return new ScopeDesc(this, p->scope_decode_offset(), | |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
2981 p->obj_decode_offset(), p->should_reexecute(), |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1250
diff
changeset
|
2982 p->return_oop()); |
0 | 2983 } |
2984 return NULL; | |
2985 } | |
2986 | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6792
diff
changeset
|
2987 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const { |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2988 if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2989 if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2990 if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2991 if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); |
1204 | 2992 if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1644
diff
changeset
|
2993 |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1644
diff
changeset
|
2994 if (has_method_handle_invokes()) |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1644
diff
changeset
|
2995 if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1644
diff
changeset
|
2996 |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2997 if (block_begin == consts_begin()) stream->print_cr("[Constants]"); |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1644
diff
changeset
|
2998 |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
2999 if (block_begin == entry_point()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3000 methodHandle m = method(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3001 if (m.not_null()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3002 stream->print(" # "); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3003 m->print_value_on(stream); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3004 stream->cr(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3005 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3006 if (m.not_null() && !is_osr_method()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3007 ResourceMark rm; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3008 int sizeargs = m->size_of_parameters(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3009 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3010 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3011 { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3012 int sig_index = 0; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3013 if (!m->is_static()) |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3014 sig_bt[sig_index++] = T_OBJECT; // 'this' |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3015 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3016 BasicType t = ss.type(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3017 sig_bt[sig_index++] = t; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3018 if (type2size[t] == 2) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3019 sig_bt[sig_index++] = T_VOID; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3020 } else { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3021 assert(type2size[t] == 1, "size is 1 or 2"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3022 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3023 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3024 assert(sig_index == sizeargs, ""); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3025 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3026 const char* spname = "sp"; // make arch-specific? |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3027 intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3028 int stack_slot_offset = this->frame_size() * wordSize; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3029 int tab1 = 14, tab2 = 24; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3030 int sig_index = 0; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3031 int arg_index = (m->is_static() ? 0 : -1); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3032 bool did_old_sp = false; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3033 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3034 bool at_this = (arg_index == -1); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3035 bool at_old_sp = false; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3036 BasicType t = (at_this ? T_OBJECT : ss.type()); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3037 assert(t == sig_bt[sig_index], "sigs in sync"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3038 if (at_this) |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3039 stream->print(" # this: "); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3040 else |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3041 stream->print(" # parm%d: ", arg_index); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3042 stream->move_to(tab1); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3043 VMReg fst = regs[sig_index].first(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3044 VMReg snd = regs[sig_index].second(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3045 if (fst->is_reg()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3046 stream->print("%s", fst->name()); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3047 if (snd->is_valid()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3048 stream->print(":%s", snd->name()); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3049 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3050 } else if (fst->is_stack()) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3051 int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3052 if (offset == stack_slot_offset) at_old_sp = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3053 stream->print("[%s+0x%x]", spname, offset); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3054 } else { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3055 stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3056 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3057 stream->print(" "); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3058 stream->move_to(tab2); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3059 stream->print("= "); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3060 if (at_this) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3061 m->method_holder()->print_value_on(stream); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3062 } else { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3063 bool did_name = false; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3064 if (!at_this && ss.is_object()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
3065 Symbol* name = ss.as_symbol_or_null(); |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3066 if (name != NULL) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3067 name->print_value_on(stream); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3068 did_name = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3069 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3070 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3071 if (!did_name) |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3072 stream->print("%s", type2name(t)); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3073 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3074 if (at_old_sp) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3075 stream->print(" (%s of caller)", spname); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3076 did_old_sp = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3077 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3078 stream->cr(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3079 sig_index += type2size[t]; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3080 arg_index += 1; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3081 if (!at_this) ss.next(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3082 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3083 if (!did_old_sp) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3084 stream->print(" # "); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3085 stream->move_to(tab1); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3086 stream->print("[%s+0x%x]", spname, stack_slot_offset); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3087 stream->print(" (%s of caller)", spname); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3088 stream->cr(); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3089 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3090 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3091 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3092 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1141
diff
changeset
|
3093 |
0 | 3094 void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) { |
3095 // First, find an oopmap in (begin, end]. | |
3096 // We use the odd half-closed interval so that oop maps and scope descs | |
3097 // which are tied to the byte after a call are printed with the call itself. | |
1748 | 3098 address base = code_begin(); |
0 | 3099 OopMapSet* oms = oop_maps(); |
3100 if (oms != NULL) { | |
3101 for (int i = 0, imax = oms->size(); i < imax; i++) { | |
3102 OopMap* om = oms->at(i); | |
3103 address pc = base + om->offset(); | |
3104 if (pc > begin) { | |
3105 if (pc <= end) { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3106 st->move_to(column); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3107 st->print("; "); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3108 om->print_on(st); |
0 | 3109 } |
3110 break; | |
3111 } | |
3112 } | |
3113 } | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3114 |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3115 // Print any debug info present at this pc. |
0 | 3116 ScopeDesc* sd = scope_desc_in(begin, end); |
3117 if (sd != NULL) { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3118 st->move_to(column); |
0 | 3119 if (sd->bci() == SynchronizationEntryBCI) { |
3120 st->print(";*synchronization entry"); | |
3121 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3122 if (sd->method() == NULL) { |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3123 st->print("method is NULL"); |
0 | 3124 } else if (sd->method()->is_native()) { |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3125 st->print("method is native"); |
0 | 3126 } else { |
2142 | 3127 Bytecodes::Code bc = sd->method()->java_code_at(sd->bci()); |
0 | 3128 st->print(";*%s", Bytecodes::name(bc)); |
3129 switch (bc) { | |
3130 case Bytecodes::_invokevirtual: | |
3131 case Bytecodes::_invokespecial: | |
3132 case Bytecodes::_invokestatic: | |
3133 case Bytecodes::_invokeinterface: | |
3134 { | |
2142 | 3135 Bytecode_invoke invoke(sd->method(), sd->bci()); |
0 | 3136 st->print(" "); |
2142 | 3137 if (invoke.name() != NULL) |
3138 invoke.name()->print_symbol_on(st); | |
0 | 3139 else |
3140 st->print("<UNKNOWN>"); | |
3141 break; | |
3142 } | |
3143 case Bytecodes::_getfield: | |
3144 case Bytecodes::_putfield: | |
3145 case Bytecodes::_getstatic: | |
3146 case Bytecodes::_putstatic: | |
3147 { | |
2142 | 3148 Bytecode_field field(sd->method(), sd->bci()); |
0 | 3149 st->print(" "); |
2142 | 3150 if (field.name() != NULL) |
3151 field.name()->print_symbol_on(st); | |
0 | 3152 else |
3153 st->print("<UNKNOWN>"); | |
3154 } | |
3155 } | |
3156 } | |
3157 } | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3158 |
0 | 3159 // Print all scopes |
3160 for (;sd != NULL; sd = sd->sender()) { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3161 st->move_to(column); |
0 | 3162 st->print("; -"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3163 if (sd->method() == NULL) { |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3164 st->print("method is NULL"); |
0 | 3165 } else { |
3166 sd->method()->print_short_name(st); | |
3167 } | |
3168 int lineno = sd->method()->line_number_from_bci(sd->bci()); | |
3169 if (lineno != -1) { | |
3170 st->print("@%d (line %d)", sd->bci(), lineno); | |
3171 } else { | |
3172 st->print("@%d", sd->bci()); | |
3173 } | |
3174 st->cr(); | |
3175 } | |
3176 } | |
3177 | |
3178 // Print relocation information | |
3179 const char* str = reloc_string_for(begin, end); | |
3180 if (str != NULL) { | |
3181 if (sd != NULL) st->cr(); | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3182 st->move_to(column); |
0 | 3183 st->print("; {%s}", str); |
3184 } | |
1748 | 3185 int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin()); |
0 | 3186 if (cont_offset != 0) { |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3187 st->move_to(column); |
1748 | 3188 st->print("; implicit exception: dispatches to " INTPTR_FORMAT, code_begin() + cont_offset); |
0 | 3189 } |
3190 | |
3191 } | |
3192 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3193 #ifndef PRODUCT |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
30
diff
changeset
|
3194 |
0 | 3195 void nmethod::print_value_on(outputStream* st) const { |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
3196 st->print("nmethod"); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2376
diff
changeset
|
3197 print_on(st, NULL); |
0 | 3198 } |
3199 | |
3200 void nmethod::print_calls(outputStream* st) { | |
3201 RelocIterator iter(this); | |
3202 while (iter.next()) { | |
3203 switch (iter.type()) { | |
3204 case relocInfo::virtual_call_type: | |
3205 case relocInfo::opt_virtual_call_type: { | |
3206 VerifyMutexLocker mc(CompiledIC_lock); | |
20277
882004b9e7e1
8047362: Add a version of CompiledIC_at that doesn't create a new RelocIterator
stefank
parents:
20269
diff
changeset
|
3207 CompiledIC_at(&iter)->print(); |
0 | 3208 break; |
3209 } | |
3210 case relocInfo::static_call_type: | |
3211 st->print_cr("Static call at " INTPTR_FORMAT, iter.reloc()->addr()); | |
3212 compiledStaticCall_at(iter.reloc())->print(); | |
3213 break; | |
3214 } | |
3215 } | |
3216 } | |
3217 | |
3218 void nmethod::print_handler_table() { | |
3219 ExceptionHandlerTable(this).print(); | |
3220 } | |
3221 | |
3222 void nmethod::print_nul_chk_table() { | |
1748 | 3223 ImplicitExceptionTable(this).print(code_begin()); |
0 | 3224 } |
3225 | |
3226 void nmethod::print_statistics() { | |
3227 ttyLocker ttyl; | |
3228 if (xtty != NULL) xtty->head("statistics type='nmethod'"); | |
3229 nmethod_stats.print_native_nmethod_stats(); | |
3230 nmethod_stats.print_nmethod_stats(); | |
3231 DebugInformationRecorder::print_statistics(); | |
3232 nmethod_stats.print_pc_stats(); | |
3233 Dependencies::print_statistics(); | |
3234 if (xtty != NULL) xtty->tail("statistics"); | |
3235 } | |
3236 | |
3237 #endif // PRODUCT |