1 /* |
1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "code/codeBlob.hpp" |
26 #include "code/codeBlob.hpp" |
27 #include "code/codeCache.hpp" |
27 #include "code/codeCache.hpp" |
|
28 #include "code/compiledIC.hpp" |
28 #include "code/dependencies.hpp" |
29 #include "code/dependencies.hpp" |
|
30 #include "code/icBuffer.hpp" |
29 #include "code/nmethod.hpp" |
31 #include "code/nmethod.hpp" |
30 #include "code/pcDesc.hpp" |
32 #include "code/pcDesc.hpp" |
31 #include "gc_implementation/shared/markSweep.hpp" |
33 #include "gc_implementation/shared/markSweep.hpp" |
32 #include "memory/allocation.inline.hpp" |
34 #include "memory/allocation.inline.hpp" |
33 #include "memory/gcLocker.hpp" |
35 #include "memory/gcLocker.hpp" |
34 #include "memory/iterator.hpp" |
36 #include "memory/iterator.hpp" |
35 #include "memory/resourceArea.hpp" |
37 #include "memory/resourceArea.hpp" |
36 #include "oops/methodOop.hpp" |
38 #include "oops/method.hpp" |
37 #include "oops/objArrayOop.hpp" |
39 #include "oops/objArrayOop.hpp" |
38 #include "oops/oop.inline.hpp" |
40 #include "oops/oop.inline.hpp" |
39 #include "runtime/handles.inline.hpp" |
41 #include "runtime/handles.inline.hpp" |
40 #include "runtime/icache.hpp" |
42 #include "runtime/icache.hpp" |
41 #include "runtime/java.hpp" |
43 #include "runtime/java.hpp" |
81 header_size * 100 / total_size, |
85 header_size * 100 / total_size, |
82 relocation_size * 100 / total_size, |
86 relocation_size * 100 / total_size, |
83 code_size * 100 / total_size, |
87 code_size * 100 / total_size, |
84 stub_size * 100 / total_size, |
88 stub_size * 100 / total_size, |
85 scopes_oop_size * 100 / total_size, |
89 scopes_oop_size * 100 / total_size, |
|
90 scopes_metadata_size * 100 / total_size, |
86 scopes_data_size * 100 / total_size, |
91 scopes_data_size * 100 / total_size, |
87 scopes_pcs_size * 100 / total_size); |
92 scopes_pcs_size * 100 / total_size); |
88 } |
93 } |
89 |
94 |
90 void add(CodeBlob* cb) { |
95 void add(CodeBlob* cb) { |
96 nmethod* nm = cb->as_nmethod_or_null(); |
101 nmethod* nm = cb->as_nmethod_or_null(); |
97 code_size += nm->insts_size(); |
102 code_size += nm->insts_size(); |
98 stub_size += nm->stub_size(); |
103 stub_size += nm->stub_size(); |
99 |
104 |
100 scopes_oop_size += nm->oops_size(); |
105 scopes_oop_size += nm->oops_size(); |
|
106 scopes_metadata_size += nm->metadata_size(); |
101 scopes_data_size += nm->scopes_data_size(); |
107 scopes_data_size += nm->scopes_data_size(); |
102 scopes_pcs_size += nm->scopes_pcs_size(); |
108 scopes_pcs_size += nm->scopes_pcs_size(); |
103 } else { |
109 } else { |
104 code_size += cb->code_size(); |
110 code_size += cb->code_size(); |
105 } |
111 } |
446 } |
458 } |
447 } |
459 } |
448 #endif //PRODUCT |
460 #endif //PRODUCT |
449 |
461 |
450 |
462 |
451 nmethod* CodeCache::find_and_remove_saved_code(methodOop m) { |
463 nmethod* CodeCache::find_and_remove_saved_code(Method* m) { |
452 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
464 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
453 nmethod* saved = _saved_nmethods; |
465 nmethod* saved = _saved_nmethods; |
454 nmethod* prev = NULL; |
466 nmethod* prev = NULL; |
455 while (saved != NULL) { |
467 while (saved != NULL) { |
456 if (saved->is_in_use() && saved->method() == m) { |
468 if (saved->is_in_use() && saved->method() == m) { |
516 nm->print_on(tty, " ### nmethod is speculatively disconnected\n"); |
528 nm->print_on(tty, " ### nmethod is speculatively disconnected\n"); |
517 } |
529 } |
518 if (LogCompilation && (xtty != NULL)) { |
530 if (LogCompilation && (xtty != NULL)) { |
519 ttyLocker ttyl; |
531 ttyLocker ttyl; |
520 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); |
532 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); |
521 xtty->method(methodOop(nm->method())); |
533 xtty->method(nm->method()); |
522 xtty->stamp(); |
534 xtty->stamp(); |
523 xtty->end_elem(); |
535 xtty->end_elem(); |
524 } |
536 } |
525 nm->method()->clear_code(); |
537 nm->method()->clear_code(); |
526 nm->set_speculatively_disconnected(true); |
538 nm->set_speculatively_disconnected(true); |
546 } |
558 } |
547 } |
559 } |
548 set_needs_cache_clean(false); |
560 set_needs_cache_clean(false); |
549 prune_scavenge_root_nmethods(); |
561 prune_scavenge_root_nmethods(); |
550 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called"); |
562 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called"); |
|
563 |
|
564 #ifdef ASSERT |
|
565 // make sure that we aren't leaking icholders |
|
566 int count = 0; |
|
567 FOR_ALL_BLOBS(cb) { |
|
568 if (cb->is_nmethod()) { |
|
569 RelocIterator iter((nmethod*)cb); |
|
570 while(iter.next()) { |
|
571 if (iter.type() == relocInfo::virtual_call_type) { |
|
572 if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) { |
|
573 CompiledIC *ic = CompiledIC_at(iter.reloc()); |
|
574 if (TraceCompiledIC) { |
|
575 tty->print("noticed icholder " INTPTR_FORMAT " ", ic->cached_icholder()); |
|
576 ic->print(); |
|
577 } |
|
578 assert(ic->cached_icholder() != NULL, "must be non-NULL"); |
|
579 count++; |
|
580 } |
|
581 } |
|
582 } |
|
583 } |
|
584 } |
|
585 |
|
586 assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() == |
|
587 CompiledICHolder::live_count(), "must agree"); |
|
588 #endif |
551 } |
589 } |
552 |
590 |
553 |
591 |
554 void CodeCache::verify_oops() { |
592 void CodeCache::verify_oops() { |
555 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
593 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
647 // which might be dependent of the fact that an interface only had one |
685 // which might be dependent of the fact that an interface only had one |
648 // implementor. |
686 // implementor. |
649 |
687 |
650 { No_Safepoint_Verifier nsv; |
688 { No_Safepoint_Verifier nsv; |
651 for (DepChange::ContextStream str(changes, nsv); str.next(); ) { |
689 for (DepChange::ContextStream str(changes, nsv); str.next(); ) { |
652 klassOop d = str.klass(); |
690 Klass* d = str.klass(); |
653 number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(changes); |
691 number_of_marked_CodeBlobs += InstanceKlass::cast(d)->mark_dependent_nmethods(changes); |
654 } |
692 } |
655 } |
693 } |
656 |
694 |
657 if (VerifyDependencies) { |
695 if (VerifyDependencies) { |
658 // Turn off dependency tracing while actually testing deps. |
696 // Turn off dependency tracing while actually testing deps. |
681 int CodeCache::mark_for_evol_deoptimization(instanceKlassHandle dependee) { |
719 int CodeCache::mark_for_evol_deoptimization(instanceKlassHandle dependee) { |
682 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
720 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
683 int number_of_marked_CodeBlobs = 0; |
721 int number_of_marked_CodeBlobs = 0; |
684 |
722 |
685 // Deoptimize all methods of the evolving class itself |
723 // Deoptimize all methods of the evolving class itself |
686 objArrayOop old_methods = dependee->methods(); |
724 Array<Method*>* old_methods = dependee->methods(); |
687 for (int i = 0; i < old_methods->length(); i++) { |
725 for (int i = 0; i < old_methods->length(); i++) { |
688 ResourceMark rm; |
726 ResourceMark rm; |
689 methodOop old_method = (methodOop) old_methods->obj_at(i); |
727 Method* old_method = old_methods->at(i); |
690 nmethod *nm = old_method->code(); |
728 nmethod *nm = old_method->code(); |
691 if (nm != NULL) { |
729 if (nm != NULL) { |
692 nm->mark_for_deoptimization(); |
730 nm->mark_for_deoptimization(); |
693 number_of_marked_CodeBlobs++; |
731 number_of_marked_CodeBlobs++; |
694 } |
732 } |
700 } else if (nm->is_evol_dependent_on(dependee())) { |
738 } else if (nm->is_evol_dependent_on(dependee())) { |
701 ResourceMark rm; |
739 ResourceMark rm; |
702 nm->mark_for_deoptimization(); |
740 nm->mark_for_deoptimization(); |
703 number_of_marked_CodeBlobs++; |
741 number_of_marked_CodeBlobs++; |
704 } else { |
742 } else { |
705 // flush caches in case they refer to a redefined methodOop |
743 // flush caches in case they refer to a redefined Method* |
706 nm->clear_inline_caches(); |
744 nm->clear_inline_caches(); |
707 } |
745 } |
708 } |
746 } |
709 |
747 |
710 return number_of_marked_CodeBlobs; |
748 return number_of_marked_CodeBlobs; |
719 nm->mark_for_deoptimization(); |
757 nm->mark_for_deoptimization(); |
720 } |
758 } |
721 } |
759 } |
722 |
760 |
723 |
761 |
724 int CodeCache::mark_for_deoptimization(methodOop dependee) { |
762 int CodeCache::mark_for_deoptimization(Method* dependee) { |
725 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
763 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
726 int number_of_marked_CodeBlobs = 0; |
764 int number_of_marked_CodeBlobs = 0; |
727 |
765 |
728 FOR_ALL_ALIVE_NMETHODS(nm) { |
766 FOR_ALL_ALIVE_NMETHODS(nm) { |
729 if (nm->is_dependent_on_method(dependee)) { |
767 if (nm->is_dependent_on_method(dependee)) { |