comparison src/share/vm/code/codeCache.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 1d7922586cf6
children 8966c2d65d96
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
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"
52 int header_size; 54 int header_size;
53 int code_size; 55 int code_size;
54 int stub_size; 56 int stub_size;
55 int relocation_size; 57 int relocation_size;
56 int scopes_oop_size; 58 int scopes_oop_size;
59 int scopes_metadata_size;
57 int scopes_data_size; 60 int scopes_data_size;
58 int scopes_pcs_size; 61 int scopes_pcs_size;
59 62
60 public: 63 public:
61 CodeBlob_sizes() { 64 CodeBlob_sizes() {
64 header_size = 0; 67 header_size = 0;
65 code_size = 0; 68 code_size = 0;
66 stub_size = 0; 69 stub_size = 0;
67 relocation_size = 0; 70 relocation_size = 0;
68 scopes_oop_size = 0; 71 scopes_oop_size = 0;
72 scopes_metadata_size = 0;
69 scopes_data_size = 0; 73 scopes_data_size = 0;
70 scopes_pcs_size = 0; 74 scopes_pcs_size = 0;
71 } 75 }
72 76
73 int total() { return total_size; } 77 int total() { return total_size; }
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 }
282 FOR_ALL_BLOBS(nm) { 288 FOR_ALL_BLOBS(nm) {
283 if (nm->is_nmethod()) f((nmethod*)nm); 289 if (nm->is_nmethod()) f((nmethod*)nm);
284 } 290 }
285 } 291 }
286 292
293 void CodeCache::alive_nmethods_do(void f(nmethod* nm)) {
294 assert_locked_or_safepoint(CodeCache_lock);
295 FOR_ALL_ALIVE_NMETHODS(nm) {
296 f(nm);
297 }
298 }
287 299
288 int CodeCache::alignment_unit() { 300 int CodeCache::alignment_unit() {
289 return (int)_heap->alignment_unit(); 301 return (int)_heap->alignment_unit();
290 } 302 }
291 303
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) {
466 saved->print_on(tty, " ### nmethod is reconnected\n"); 478 saved->print_on(tty, " ### nmethod is reconnected\n");
467 } 479 }
468 if (LogCompilation && (xtty != NULL)) { 480 if (LogCompilation && (xtty != NULL)) {
469 ttyLocker ttyl; 481 ttyLocker ttyl;
470 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id()); 482 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id());
471 xtty->method(methodOop(m)); 483 xtty->method(m);
472 xtty->stamp(); 484 xtty->stamp();
473 xtty->end_elem(); 485 xtty->end_elem();
474 } 486 }
475 return saved; 487 return saved;
476 } 488 }
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)) {