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