Mercurial > hg > truffle
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)) { |