146 (intptr_t)_heap->begin(), (intptr_t)_heap->end(), |
147 (intptr_t)_heap->begin(), (intptr_t)_heap->end(), |
147 (address)_heap->end() - (address)_heap->begin()); |
148 (address)_heap->end() - (address)_heap->begin()); |
148 } |
149 } |
149 } |
150 } |
150 verify_if_often(); |
151 verify_if_often(); |
151 if (PrintCodeCache2) { // Need to add a new flag |
152 print_trace("allocation", cb, size); |
152 ResourceMark rm; |
|
153 tty->print_cr("CodeCache allocation: addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, size); |
|
154 } |
|
155 return cb; |
153 return cb; |
156 } |
154 } |
157 |
155 |
158 void CodeCache::free(CodeBlob* cb) { |
156 void CodeCache::free(CodeBlob* cb) { |
159 assert_locked_or_safepoint(CodeCache_lock); |
157 assert_locked_or_safepoint(CodeCache_lock); |
160 verify_if_often(); |
158 verify_if_often(); |
161 |
159 |
162 if (PrintCodeCache2) { // Need to add a new flag |
160 print_trace("free", cb); |
163 ResourceMark rm; |
|
164 tty->print_cr("CodeCache free: addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, cb->size()); |
|
165 } |
|
166 if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) { |
161 if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) { |
167 _number_of_nmethods_with_dependencies--; |
162 _number_of_nmethods_with_dependencies--; |
168 } |
163 } |
169 _number_of_blobs--; |
164 _number_of_blobs--; |
170 |
165 |
258 FOR_ALL_ALIVE_BLOBS(cb) { |
253 FOR_ALL_ALIVE_BLOBS(cb) { |
259 cb->do_unloading(is_alive, keep_alive, unloading_occurred); |
254 cb->do_unloading(is_alive, keep_alive, unloading_occurred); |
260 } |
255 } |
261 } |
256 } |
262 |
257 |
263 void CodeCache::oops_do(OopClosure* f) { |
258 void CodeCache::blobs_do(CodeBlobClosure* f) { |
264 assert_locked_or_safepoint(CodeCache_lock); |
259 assert_locked_or_safepoint(CodeCache_lock); |
265 FOR_ALL_ALIVE_BLOBS(cb) { |
260 FOR_ALL_ALIVE_BLOBS(cb) { |
266 cb->oops_do(f); |
261 f->do_code_blob(cb); |
267 } |
262 |
268 } |
263 #ifdef ASSERT |
|
264 if (cb->is_nmethod()) |
|
265 ((nmethod*)cb)->verify_scavenge_root_oops(); |
|
266 #endif //ASSERT |
|
267 } |
|
268 } |
|
269 |
|
270 // Walk the list of methods which might contain non-perm oops. |
|
271 void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) { |
|
272 assert_locked_or_safepoint(CodeCache_lock); |
|
273 debug_only(mark_scavenge_root_nmethods()); |
|
274 |
|
275 for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { |
|
276 debug_only(cur->clear_scavenge_root_marked()); |
|
277 assert(cur->scavenge_root_not_marked(), ""); |
|
278 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); |
|
279 |
|
280 bool is_live = (!cur->is_zombie() && !cur->is_unloaded()); |
|
281 #ifndef PRODUCT |
|
282 if (TraceScavenge) { |
|
283 cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr(); |
|
284 } |
|
285 #endif //PRODUCT |
|
286 if (is_live) |
|
287 // Perform cur->oops_do(f), maybe just once per nmethod. |
|
288 f->do_code_blob(cur); |
|
289 } |
|
290 |
|
291 // Check for stray marks. |
|
292 debug_only(verify_perm_nmethods(NULL)); |
|
293 } |
|
294 |
|
295 void CodeCache::add_scavenge_root_nmethod(nmethod* nm) { |
|
296 assert_locked_or_safepoint(CodeCache_lock); |
|
297 nm->set_on_scavenge_root_list(); |
|
298 nm->set_scavenge_root_link(_scavenge_root_nmethods); |
|
299 set_scavenge_root_nmethods(nm); |
|
300 print_trace("add_scavenge_root", nm); |
|
301 } |
|
302 |
|
303 void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) { |
|
304 assert_locked_or_safepoint(CodeCache_lock); |
|
305 print_trace("drop_scavenge_root", nm); |
|
306 nmethod* last = NULL; |
|
307 nmethod* cur = scavenge_root_nmethods(); |
|
308 while (cur != NULL) { |
|
309 nmethod* next = cur->scavenge_root_link(); |
|
310 if (cur == nm) { |
|
311 if (last != NULL) |
|
312 last->set_scavenge_root_link(next); |
|
313 else set_scavenge_root_nmethods(next); |
|
314 nm->set_scavenge_root_link(NULL); |
|
315 nm->clear_on_scavenge_root_list(); |
|
316 return; |
|
317 } |
|
318 last = cur; |
|
319 cur = next; |
|
320 } |
|
321 assert(false, "should have been on list"); |
|
322 } |
|
323 |
|
324 void CodeCache::prune_scavenge_root_nmethods() { |
|
325 assert_locked_or_safepoint(CodeCache_lock); |
|
326 debug_only(mark_scavenge_root_nmethods()); |
|
327 |
|
328 nmethod* last = NULL; |
|
329 nmethod* cur = scavenge_root_nmethods(); |
|
330 while (cur != NULL) { |
|
331 nmethod* next = cur->scavenge_root_link(); |
|
332 debug_only(cur->clear_scavenge_root_marked()); |
|
333 assert(cur->scavenge_root_not_marked(), ""); |
|
334 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); |
|
335 |
|
336 if (!cur->is_zombie() && !cur->is_unloaded() |
|
337 && cur->detect_scavenge_root_oops()) { |
|
338 // Keep it. Advance 'last' to prevent deletion. |
|
339 last = cur; |
|
340 } else { |
|
341 // Prune it from the list, so we don't have to look at it any more. |
|
342 print_trace("prune_scavenge_root", cur); |
|
343 cur->set_scavenge_root_link(NULL); |
|
344 cur->clear_on_scavenge_root_list(); |
|
345 if (last != NULL) |
|
346 last->set_scavenge_root_link(next); |
|
347 else set_scavenge_root_nmethods(next); |
|
348 } |
|
349 cur = next; |
|
350 } |
|
351 |
|
352 // Check for stray marks. |
|
353 debug_only(verify_perm_nmethods(NULL)); |
|
354 } |
|
355 |
|
356 #ifndef PRODUCT |
|
357 void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) { |
|
358 // While we are here, verify the integrity of the list. |
|
359 mark_scavenge_root_nmethods(); |
|
360 for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { |
|
361 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); |
|
362 cur->clear_scavenge_root_marked(); |
|
363 } |
|
364 verify_perm_nmethods(f); |
|
365 } |
|
366 |
|
367 // Temporarily mark nmethods that are claimed to be on the non-perm list. |
|
368 void CodeCache::mark_scavenge_root_nmethods() { |
|
369 FOR_ALL_ALIVE_BLOBS(cb) { |
|
370 if (cb->is_nmethod()) { |
|
371 nmethod *nm = (nmethod*)cb; |
|
372 assert(nm->scavenge_root_not_marked(), "clean state"); |
|
373 if (nm->on_scavenge_root_list()) |
|
374 nm->set_scavenge_root_marked(); |
|
375 } |
|
376 } |
|
377 } |
|
378 |
|
379 // If the closure is given, run it on the unlisted nmethods. |
|
380 // Also make sure that the effects of mark_scavenge_root_nmethods is gone. |
|
381 void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) { |
|
382 FOR_ALL_ALIVE_BLOBS(cb) { |
|
383 bool call_f = (f_or_null != NULL); |
|
384 if (cb->is_nmethod()) { |
|
385 nmethod *nm = (nmethod*)cb; |
|
386 assert(nm->scavenge_root_not_marked(), "must be already processed"); |
|
387 if (nm->on_scavenge_root_list()) |
|
388 call_f = false; // don't show this one to the client |
|
389 nm->verify_scavenge_root_oops(); |
|
390 } else { |
|
391 call_f = false; // not an nmethod |
|
392 } |
|
393 if (call_f) f_or_null->do_code_blob(cb); |
|
394 } |
|
395 } |
|
396 #endif //PRODUCT |
269 |
397 |
270 void CodeCache::gc_prologue() { |
398 void CodeCache::gc_prologue() { |
|
399 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called"); |
271 } |
400 } |
272 |
401 |
273 |
402 |
274 void CodeCache::gc_epilogue() { |
403 void CodeCache::gc_epilogue() { |
275 assert_locked_or_safepoint(CodeCache_lock); |
404 assert_locked_or_safepoint(CodeCache_lock); |