Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.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 | c92a79900986 |
children | 685df3c6f84b |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
27 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" | 27 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" |
28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" | 28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" |
29 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" | 29 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" |
30 #include "gc_implementation/shared/liveRange.hpp" | 30 #include "gc_implementation/shared/liveRange.hpp" |
31 #include "gc_implementation/shared/spaceDecorator.hpp" | 31 #include "gc_implementation/shared/spaceDecorator.hpp" |
32 #include "gc_interface/collectedHeap.hpp" | 32 #include "gc_interface/collectedHeap.inline.hpp" |
33 #include "memory/allocation.inline.hpp" | 33 #include "memory/allocation.inline.hpp" |
34 #include "memory/blockOffsetTable.inline.hpp" | 34 #include "memory/blockOffsetTable.inline.hpp" |
35 #include "memory/resourceArea.hpp" | 35 #include "memory/resourceArea.hpp" |
36 #include "memory/universe.inline.hpp" | 36 #include "memory/universe.inline.hpp" |
37 #include "oops/oop.inline.hpp" | 37 #include "oops/oop.inline.hpp" |
656 HeapWord* bottom, HeapWord* top, \ | 656 HeapWord* bottom, HeapWord* top, \ |
657 ClosureType* cl); \ | 657 ClosureType* cl); \ |
658 void walk_mem_region_with_cl_nopar(MemRegion mr, \ | 658 void walk_mem_region_with_cl_nopar(MemRegion mr, \ |
659 HeapWord* bottom, HeapWord* top, \ | 659 HeapWord* bottom, HeapWord* top, \ |
660 ClosureType* cl) | 660 ClosureType* cl) |
661 walk_mem_region_with_cl_DECL(OopClosure); | 661 walk_mem_region_with_cl_DECL(ExtendedOopClosure); |
662 walk_mem_region_with_cl_DECL(FilteringClosure); | 662 walk_mem_region_with_cl_DECL(FilteringClosure); |
663 | 663 |
664 public: | 664 public: |
665 FreeListSpace_DCTOC(CompactibleFreeListSpace* sp, | 665 FreeListSpace_DCTOC(CompactibleFreeListSpace* sp, |
666 CMSCollector* collector, | 666 CMSCollector* collector, |
667 OopClosure* cl, | 667 ExtendedOopClosure* cl, |
668 CardTableModRefBS::PrecisionStyle precision, | 668 CardTableModRefBS::PrecisionStyle precision, |
669 HeapWord* boundary) : | 669 HeapWord* boundary) : |
670 Filtering_DCTOC(sp, cl, precision, boundary), | 670 Filtering_DCTOC(sp, cl, precision, boundary), |
671 _cfls(sp), _collector(collector) {} | 671 _cfls(sp), _collector(collector) {} |
672 }; | 672 }; |
744 } | 744 } |
745 | 745 |
746 // (There are only two of these, rather than N, because the split is due | 746 // (There are only two of these, rather than N, because the split is due |
747 // only to the introduction of the FilteringClosure, a local part of the | 747 // only to the introduction of the FilteringClosure, a local part of the |
748 // impl of this abstraction.) | 748 // impl of this abstraction.) |
749 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(OopClosure) | 749 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(ExtendedOopClosure) |
750 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure) | 750 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure) |
751 | 751 |
752 DirtyCardToOopClosure* | 752 DirtyCardToOopClosure* |
753 CompactibleFreeListSpace::new_dcto_cl(OopClosure* cl, | 753 CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl, |
754 CardTableModRefBS::PrecisionStyle precision, | 754 CardTableModRefBS::PrecisionStyle precision, |
755 HeapWord* boundary) { | 755 HeapWord* boundary) { |
756 return new FreeListSpace_DCTOC(this, _collector, cl, precision, boundary); | 756 return new FreeListSpace_DCTOC(this, _collector, cl, precision, boundary); |
757 } | 757 } |
758 | 758 |
779 for (cur = bottom(), limit = end(); cur < limit; | 779 for (cur = bottom(), limit = end(); cur < limit; |
780 cur += cl->do_blk(cur)); | 780 cur += cl->do_blk(cur)); |
781 } | 781 } |
782 | 782 |
783 // Apply the given closure to each oop in the space. | 783 // Apply the given closure to each oop in the space. |
784 void CompactibleFreeListSpace::oop_iterate(OopClosure* cl) { | 784 void CompactibleFreeListSpace::oop_iterate(ExtendedOopClosure* cl) { |
785 assert_lock_strong(freelistLock()); | 785 assert_lock_strong(freelistLock()); |
786 HeapWord *cur, *limit; | 786 HeapWord *cur, *limit; |
787 size_t curSize; | 787 size_t curSize; |
788 for (cur = bottom(), limit = end(); cur < limit; | 788 for (cur = bottom(), limit = end(); cur < limit; |
789 cur += curSize) { | 789 cur += curSize) { |
793 } | 793 } |
794 } | 794 } |
795 } | 795 } |
796 | 796 |
797 // Apply the given closure to each oop in the space \intersect memory region. | 797 // Apply the given closure to each oop in the space \intersect memory region. |
798 void CompactibleFreeListSpace::oop_iterate(MemRegion mr, OopClosure* cl) { | 798 void CompactibleFreeListSpace::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) { |
799 assert_lock_strong(freelistLock()); | 799 assert_lock_strong(freelistLock()); |
800 if (is_empty()) { | 800 if (is_empty()) { |
801 return; | 801 return; |
802 } | 802 } |
803 MemRegion cur = MemRegion(bottom(), end()); | 803 MemRegion cur = MemRegion(bottom(), end()); |
1004 assert(res != 0, "Block size should not be 0"); | 1004 assert(res != 0, "Block size should not be 0"); |
1005 return res; | 1005 return res; |
1006 } | 1006 } |
1007 } else { | 1007 } else { |
1008 // must read from what 'p' points to in each loop. | 1008 // must read from what 'p' points to in each loop. |
1009 klassOop k = ((volatile oopDesc*)p)->klass_or_null(); | 1009 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); |
1010 if (k != NULL) { | 1010 if (k != NULL) { |
1011 assert(k->is_oop(true /* ignore mark word */), "Should be klass oop"); | 1011 assert(k->is_klass(), "Should really be klass oop."); |
1012 oop o = (oop)p; | 1012 oop o = (oop)p; |
1013 assert(o->is_parsable(), "Should be parsable"); | |
1014 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); | 1013 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); |
1015 size_t res = o->size_given_klass(k->klass_part()); | 1014 size_t res = o->size_given_klass(k); |
1016 res = adjustObjectSize(res); | 1015 res = adjustObjectSize(res); |
1017 assert(res != 0, "Block size should not be 0"); | 1016 assert(res != 0, "Block size should not be 0"); |
1018 return res; | 1017 return res; |
1019 } | 1018 } |
1020 } | 1019 } |
1021 } | 1020 } |
1022 } | 1021 } |
1023 | 1022 |
1023 // TODO: Now that is_parsable is gone, we should combine these two functions. | |
1024 // A variant of the above that uses the Printezis bits for | 1024 // A variant of the above that uses the Printezis bits for |
1025 // unparsable but allocated objects. This avoids any possible | 1025 // unparsable but allocated objects. This avoids any possible |
1026 // stalls waiting for mutators to initialize objects, and is | 1026 // stalls waiting for mutators to initialize objects, and is |
1027 // thus potentially faster than the variant above. However, | 1027 // thus potentially faster than the variant above. However, |
1028 // this variant may return a zero size for a block that is | 1028 // this variant may return a zero size for a block that is |
1046 assert(loops == 0, "Should be 0"); | 1046 assert(loops == 0, "Should be 0"); |
1047 return res; | 1047 return res; |
1048 } | 1048 } |
1049 } else { | 1049 } else { |
1050 // must read from what 'p' points to in each loop. | 1050 // must read from what 'p' points to in each loop. |
1051 klassOop k = ((volatile oopDesc*)p)->klass_or_null(); | 1051 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); |
1052 // We trust the size of any object that has a non-NULL | 1052 // We trust the size of any object that has a non-NULL |
1053 // klass and (for those in the perm gen) is parsable | 1053 // klass and (for those in the perm gen) is parsable |
1054 // -- irrespective of its conc_safe-ty. | 1054 // -- irrespective of its conc_safe-ty. |
1055 if (k != NULL && ((oopDesc*)p)->is_parsable()) { | 1055 if (k != NULL) { |
1056 assert(k->is_oop(), "Should really be klass oop."); | 1056 assert(k->is_klass(), "Should really be klass oop."); |
1057 oop o = (oop)p; | 1057 oop o = (oop)p; |
1058 assert(o->is_oop(), "Should be an oop"); | 1058 assert(o->is_oop(), "Should be an oop"); |
1059 size_t res = o->size_given_klass(k->klass_part()); | 1059 size_t res = o->size_given_klass(k); |
1060 res = adjustObjectSize(res); | 1060 res = adjustObjectSize(res); |
1061 assert(res != 0, "Block size should not be 0"); | 1061 assert(res != 0, "Block size should not be 0"); |
1062 return res; | 1062 return res; |
1063 } else { | 1063 } else { |
1064 // May return 0 if P-bits not present. | 1064 // May return 0 if P-bits not present. |
1101 // and those objects (if garbage) may have been modified to hold | 1101 // and those objects (if garbage) may have been modified to hold |
1102 // live range information. | 1102 // live range information. |
1103 // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, | 1103 // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, |
1104 // "Should be a block boundary"); | 1104 // "Should be a block boundary"); |
1105 if (FreeChunk::indicatesFreeChunk(p)) return false; | 1105 if (FreeChunk::indicatesFreeChunk(p)) return false; |
1106 klassOop k = oop(p)->klass_or_null(); | 1106 Klass* k = oop(p)->klass_or_null(); |
1107 if (k != NULL) { | 1107 if (k != NULL) { |
1108 // Ignore mark word because it may have been used to | 1108 // Ignore mark word because it may have been used to |
1109 // chain together promoted objects (the last one | 1109 // chain together promoted objects (the last one |
1110 // would have a null value). | 1110 // would have a null value). |
1111 assert(oop(p)->is_oop(true), "Should be an oop"); | 1111 assert(oop(p)->is_oop(true), "Should be an oop"); |
1138 // in jmap not reporting certain perm gen objects. This will be moot | 1138 // in jmap not reporting certain perm gen objects. This will be moot |
1139 // if/when the perm gen goes away in the future. | 1139 // if/when the perm gen goes away in the future. |
1140 if (_collector->abstract_state() == CMSCollector::Sweeping) { | 1140 if (_collector->abstract_state() == CMSCollector::Sweeping) { |
1141 CMSBitMap* live_map = _collector->markBitMap(); | 1141 CMSBitMap* live_map = _collector->markBitMap(); |
1142 return live_map->par_isMarked((HeapWord*) p); | 1142 return live_map->par_isMarked((HeapWord*) p); |
1143 } else { | |
1144 // If we're not currently sweeping and we haven't swept the perm gen in | |
1145 // the previous concurrent cycle then we may have dead but unswept objects | |
1146 // in the perm gen. In this case, we use the "deadness" information | |
1147 // that we had saved in perm_gen_verify_bit_map at the last sweep. | |
1148 if (!CMSClassUnloadingEnabled && _collector->_permGen->reserved().contains(p)) { | |
1149 if (_collector->verifying()) { | |
1150 CMSBitMap* dead_map = _collector->perm_gen_verify_bit_map(); | |
1151 // Object is marked in the dead_map bitmap at the previous sweep | |
1152 // when we know that it's dead; if the bitmap is not allocated then | |
1153 // the object is alive. | |
1154 return (dead_map->sizeInBits() == 0) // bit_map has been allocated | |
1155 || !dead_map->par_isMarked((HeapWord*) p); | |
1156 } else { | |
1157 return false; // We can't say for sure if it's live, so we say that it's dead. | |
1158 } | |
1159 } | |
1160 } | 1143 } |
1161 return true; | 1144 return true; |
1162 } | 1145 } |
1163 | 1146 |
1164 bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const { | 1147 bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const { |
2440 | 2423 |
2441 public: | 2424 public: |
2442 VerifyAllOopsClosure(const CMSCollector* collector, | 2425 VerifyAllOopsClosure(const CMSCollector* collector, |
2443 const CompactibleFreeListSpace* sp, MemRegion span, | 2426 const CompactibleFreeListSpace* sp, MemRegion span, |
2444 bool past_remark, CMSBitMap* bit_map) : | 2427 bool past_remark, CMSBitMap* bit_map) : |
2445 OopClosure(), _collector(collector), _sp(sp), _span(span), | 2428 _collector(collector), _sp(sp), _span(span), |
2446 _past_remark(past_remark), _bit_map(bit_map) { } | 2429 _past_remark(past_remark), _bit_map(bit_map) { } |
2447 | 2430 |
2448 virtual void do_oop(oop* p) { VerifyAllOopsClosure::do_oop_work(p); } | 2431 virtual void do_oop(oop* p) { VerifyAllOopsClosure::do_oop_work(p); } |
2449 virtual void do_oop(narrowOop* p) { VerifyAllOopsClosure::do_oop_work(p); } | 2432 virtual void do_oop(narrowOop* p) { VerifyAllOopsClosure::do_oop_work(p); } |
2450 }; | 2433 }; |
2476 if (FLSVerifyAllHeapReferences) | 2459 if (FLSVerifyAllHeapReferences) |
2477 { | 2460 { |
2478 VerifyAllOopsClosure cl(_collector, this, span, past_remark, | 2461 VerifyAllOopsClosure cl(_collector, this, span, past_remark, |
2479 _collector->markBitMap()); | 2462 _collector->markBitMap()); |
2480 CollectedHeap* ch = Universe::heap(); | 2463 CollectedHeap* ch = Universe::heap(); |
2481 ch->oop_iterate(&cl); // all oops in generations | 2464 |
2482 ch->permanent_oop_iterate(&cl); // all oops in perm gen | 2465 // Iterate over all oops in the heap. Uses the _no_header version |
2466 // since we are not interested in following the klass pointers. | |
2467 ch->oop_iterate_no_header(&cl); | |
2483 } | 2468 } |
2484 | 2469 |
2485 if (VerifyObjectStartArray) { | 2470 if (VerifyObjectStartArray) { |
2486 // Verify the block offset table | 2471 // Verify the block offset table |
2487 _bt.verify(); | 2472 _bt.verify(); |