comparison src/share/vm/code/codeCache.cpp @ 989:148e5441d916

6863023: need non-perm oops in code cache for JSR 292 Summary: Make a special root-list for those few nmethods which might contain non-perm oops. Reviewed-by: twisti, kvn, never, jmasa, ysr
author jrose
date Tue, 15 Sep 2009 21:53:47 -0700
parents a61af66fc99e
children 5f24d0319e54
comparison
equal deleted inserted replaced
987:00977607da34 989:148e5441d916
93 93
94 CodeHeap * CodeCache::_heap = new CodeHeap(); 94 CodeHeap * CodeCache::_heap = new CodeHeap();
95 int CodeCache::_number_of_blobs = 0; 95 int CodeCache::_number_of_blobs = 0;
96 int CodeCache::_number_of_nmethods_with_dependencies = 0; 96 int CodeCache::_number_of_nmethods_with_dependencies = 0;
97 bool CodeCache::_needs_cache_clean = false; 97 bool CodeCache::_needs_cache_clean = false;
98 nmethod* CodeCache::_scavenge_root_nmethods = NULL;
98 99
99 100
100 CodeBlob* CodeCache::first() { 101 CodeBlob* CodeCache::first() {
101 assert_locked_or_safepoint(CodeCache_lock); 102 assert_locked_or_safepoint(CodeCache_lock);
102 return (CodeBlob*)_heap->first(); 103 return (CodeBlob*)_heap->first();
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);
283 debug_only(nm->verify();) 412 debug_only(nm->verify();)
284 } 413 }
285 cb->fix_oop_relocations(); 414 cb->fix_oop_relocations();
286 } 415 }
287 set_needs_cache_clean(false); 416 set_needs_cache_clean(false);
417 prune_scavenge_root_nmethods();
418 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
288 } 419 }
289 420
290 421
291 address CodeCache::first_address() { 422 address CodeCache::first_address() {
292 assert_locked_or_safepoint(CodeCache_lock); 423 assert_locked_or_safepoint(CodeCache_lock);
503 #ifndef PRODUCT 634 #ifndef PRODUCT
504 635
505 void CodeCache::verify_if_often() { 636 void CodeCache::verify_if_often() {
506 if (VerifyCodeCacheOften) { 637 if (VerifyCodeCacheOften) {
507 _heap->verify(); 638 _heap->verify();
639 }
640 }
641
642 void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
643 if (PrintCodeCache2) { // Need to add a new flag
644 ResourceMark rm;
645 if (size == 0) size = cb->size();
646 tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size);
508 } 647 }
509 } 648 }
510 649
511 void CodeCache::print_internals() { 650 void CodeCache::print_internals() {
512 int nmethodCount = 0; 651 int nmethodCount = 0;