4668 } |
4668 } |
4669 _count++; |
4669 _count++; |
4670 } |
4670 } |
4671 }; |
4671 }; |
4672 |
4672 |
|
4673 class G1CodeBlobClosure : public CodeBlobClosure { |
|
4674 class HeapRegionGatheringOopClosure : public OopClosure { |
|
4675 G1CollectedHeap* _g1h; |
|
4676 OopClosure* _work; |
|
4677 nmethod* _nm; |
|
4678 |
|
4679 template <typename T> |
|
4680 void do_oop_work(T* p) { |
|
4681 _work->do_oop(p); |
|
4682 T oop_or_narrowoop = oopDesc::load_heap_oop(p); |
|
4683 if (!oopDesc::is_null(oop_or_narrowoop)) { |
|
4684 oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); |
|
4685 HeapRegion* hr = _g1h->heap_region_containing_raw(o); |
|
4686 assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset"); |
|
4687 hr->add_strong_code_root(_nm); |
|
4688 } |
|
4689 } |
|
4690 |
|
4691 public: |
|
4692 HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} |
|
4693 |
|
4694 void do_oop(oop* o) { |
|
4695 do_oop_work(o); |
|
4696 } |
|
4697 |
|
4698 void do_oop(narrowOop* o) { |
|
4699 do_oop_work(o); |
|
4700 } |
|
4701 |
|
4702 void set_nm(nmethod* nm) { |
|
4703 _nm = nm; |
|
4704 } |
|
4705 }; |
|
4706 |
|
4707 HeapRegionGatheringOopClosure _oc; |
|
4708 public: |
|
4709 G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} |
|
4710 |
|
4711 void do_code_blob(CodeBlob* cb) { |
|
4712 nmethod* nm = cb->as_nmethod_or_null(); |
|
4713 if (nm != NULL) { |
|
4714 if (!nm->test_set_oops_do_mark()) { |
|
4715 _oc.set_nm(nm); |
|
4716 nm->oops_do(&_oc); |
|
4717 nm->fix_oop_relocations(); |
|
4718 } |
|
4719 } |
|
4720 } |
|
4721 }; |
|
4722 |
4673 class G1ParTask : public AbstractGangTask { |
4723 class G1ParTask : public AbstractGangTask { |
4674 protected: |
4724 protected: |
4675 G1CollectedHeap* _g1h; |
4725 G1CollectedHeap* _g1h; |
4676 RefToScanQueueSet *_queues; |
4726 RefToScanQueueSet *_queues; |
4677 ParallelTaskTerminator _terminator; |
4727 ParallelTaskTerminator _terminator; |
4733 |
4783 |
4734 } |
4784 } |
4735 |
4785 |
4736 void do_cld(ClassLoaderData* cld) { |
4786 void do_cld(ClassLoaderData* cld) { |
4737 cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim); |
4787 cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim); |
4738 } |
|
4739 }; |
|
4740 |
|
4741 class G1CodeBlobClosure: public CodeBlobClosure { |
|
4742 OopClosure* _f; |
|
4743 |
|
4744 public: |
|
4745 G1CodeBlobClosure(OopClosure* f) : _f(f) {} |
|
4746 void do_code_blob(CodeBlob* blob) { |
|
4747 nmethod* that = blob->as_nmethod_or_null(); |
|
4748 if (that != NULL) { |
|
4749 if (!that->test_set_oops_do_mark()) { |
|
4750 that->oops_do(_f); |
|
4751 that->fix_oop_relocations(); |
|
4752 } |
|
4753 } |
|
4754 } |
4788 } |
4755 }; |
4789 }; |
4756 |
4790 |
4757 void work(uint worker_id) { |
4791 void work(uint worker_id) { |
4758 if (worker_id >= _n_workers) return; // no work needed this round |
4792 if (worker_id >= _n_workers) return; // no work needed this round |
4942 } |
4976 } |
4943 } |
4977 } |
4944 g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms); |
4978 g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms); |
4945 |
4979 |
4946 // Now scan the complement of the collection set. |
4980 // Now scan the complement of the collection set. |
4947 MarkingCodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots, CodeBlobToOopClosure::FixRelocations); |
4981 G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); |
4948 |
4982 |
4949 g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); |
4983 g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); |
4950 |
4984 |
4951 _process_strong_tasks->all_tasks_completed(); |
4985 _process_strong_tasks->all_tasks_completed(); |
4952 } |
4986 } |
5988 // Reset and re-enable the hot card cache. |
6022 // Reset and re-enable the hot card cache. |
5989 // Note the counts for the cards in the regions in the |
6023 // Note the counts for the cards in the regions in the |
5990 // collection set are reset when the collection set is freed. |
6024 // collection set are reset when the collection set is freed. |
5991 hot_card_cache->reset_hot_cache(); |
6025 hot_card_cache->reset_hot_cache(); |
5992 hot_card_cache->set_use_cache(true); |
6026 hot_card_cache->set_use_cache(true); |
5993 |
|
5994 // Migrate the strong code roots attached to each region in |
|
5995 // the collection set. Ideally we would like to do this |
|
5996 // after we have finished the scanning/evacuation of the |
|
5997 // strong code roots for a particular heap region. |
|
5998 migrate_strong_code_roots(); |
|
5999 |
6027 |
6000 purge_code_root_memory(); |
6028 purge_code_root_memory(); |
6001 |
6029 |
6002 if (g1_policy()->during_initial_mark_pause()) { |
6030 if (g1_policy()->during_initial_mark_pause()) { |
6003 // Reset the claim values set during marking the strong code roots |
6031 // Reset the claim values set during marking the strong code roots |
7047 assert(!hr->continuesHumongous(), |
7075 assert(!hr->continuesHumongous(), |
7048 err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
7076 err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
7049 " starting at "HR_FORMAT, |
7077 " starting at "HR_FORMAT, |
7050 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
7078 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
7051 |
7079 |
7052 // HeapRegion::add_strong_code_root() avoids adding duplicate |
7080 // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries. |
7053 // entries but having duplicates is OK since we "mark" nmethods |
7081 hr->add_strong_code_root_locked(_nm); |
7054 // as visited when we scan the strong code root lists during the GC. |
|
7055 hr->add_strong_code_root(_nm); |
|
7056 assert(hr->rem_set()->strong_code_roots_list_contains(_nm), |
|
7057 err_msg("failed to add code root "PTR_FORMAT" to remembered set of region "HR_FORMAT, |
|
7058 _nm, HR_FORMAT_PARAMS(hr))); |
|
7059 } |
7082 } |
7060 } |
7083 } |
7061 |
7084 |
7062 public: |
7085 public: |
7063 RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
7086 RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
7080 err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
7103 err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
7081 " starting at "HR_FORMAT, |
7104 " starting at "HR_FORMAT, |
7082 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
7105 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
7083 |
7106 |
7084 hr->remove_strong_code_root(_nm); |
7107 hr->remove_strong_code_root(_nm); |
7085 assert(!hr->rem_set()->strong_code_roots_list_contains(_nm), |
|
7086 err_msg("failed to remove code root "PTR_FORMAT" of region "HR_FORMAT, |
|
7087 _nm, HR_FORMAT_PARAMS(hr))); |
|
7088 } |
7108 } |
7089 } |
7109 } |
7090 |
7110 |
7091 public: |
7111 public: |
7092 UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
7112 UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
7110 guarantee(nm != NULL, "sanity"); |
7130 guarantee(nm != NULL, "sanity"); |
7111 UnregisterNMethodOopClosure reg_cl(this, nm); |
7131 UnregisterNMethodOopClosure reg_cl(this, nm); |
7112 nm->oops_do(®_cl, true); |
7132 nm->oops_do(®_cl, true); |
7113 } |
7133 } |
7114 |
7134 |
7115 class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure { |
|
7116 public: |
|
7117 bool doHeapRegion(HeapRegion *hr) { |
|
7118 assert(!hr->isHumongous(), |
|
7119 err_msg("humongous region "HR_FORMAT" should not have been added to collection set", |
|
7120 HR_FORMAT_PARAMS(hr))); |
|
7121 hr->migrate_strong_code_roots(); |
|
7122 return false; |
|
7123 } |
|
7124 }; |
|
7125 |
|
7126 void G1CollectedHeap::migrate_strong_code_roots() { |
|
7127 MigrateCodeRootsHeapRegionClosure cl; |
|
7128 double migrate_start = os::elapsedTime(); |
|
7129 collection_set_iterate(&cl); |
|
7130 double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0; |
|
7131 g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms); |
|
7132 } |
|
7133 |
|
7134 void G1CollectedHeap::purge_code_root_memory() { |
7135 void G1CollectedHeap::purge_code_root_memory() { |
7135 double purge_start = os::elapsedTime(); |
7136 double purge_start = os::elapsedTime(); |
7136 G1CodeRootSet::purge_chunks(G1CodeRootsChunkCacheKeepPercent); |
7137 G1CodeRootSet::purge(); |
7137 double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0; |
7138 double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0; |
7138 g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms); |
7139 g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms); |
7139 } |
7140 } |
7140 |
7141 |
7141 class RebuildStrongCodeRootClosure: public CodeBlobClosure { |
7142 class RebuildStrongCodeRootClosure: public CodeBlobClosure { |