4578 } |
4578 } |
4579 _count++; |
4579 _count++; |
4580 } |
4580 } |
4581 }; |
4581 }; |
4582 |
4582 |
|
4583 class G1CodeBlobClosure : public CodeBlobClosure { |
|
4584 class HeapRegionGatheringOopClosure : public OopClosure { |
|
4585 G1CollectedHeap* _g1h; |
|
4586 OopClosure* _work; |
|
4587 nmethod* _nm; |
|
4588 |
|
4589 template <typename T> |
|
4590 void do_oop_work(T* p) { |
|
4591 _work->do_oop(p); |
|
4592 T oop_or_narrowoop = oopDesc::load_heap_oop(p); |
|
4593 if (!oopDesc::is_null(oop_or_narrowoop)) { |
|
4594 oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); |
|
4595 HeapRegion* hr = _g1h->heap_region_containing_raw(o); |
|
4596 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"); |
|
4597 hr->add_strong_code_root(_nm); |
|
4598 } |
|
4599 } |
|
4600 |
|
4601 public: |
|
4602 HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} |
|
4603 |
|
4604 void do_oop(oop* o) { |
|
4605 do_oop_work(o); |
|
4606 } |
|
4607 |
|
4608 void do_oop(narrowOop* o) { |
|
4609 do_oop_work(o); |
|
4610 } |
|
4611 |
|
4612 void set_nm(nmethod* nm) { |
|
4613 _nm = nm; |
|
4614 } |
|
4615 }; |
|
4616 |
|
4617 HeapRegionGatheringOopClosure _oc; |
|
4618 public: |
|
4619 G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} |
|
4620 |
|
4621 void do_code_blob(CodeBlob* cb) { |
|
4622 nmethod* nm = cb->as_nmethod_or_null(); |
|
4623 if (nm != NULL) { |
|
4624 if (!nm->test_set_oops_do_mark()) { |
|
4625 _oc.set_nm(nm); |
|
4626 nm->oops_do(&_oc); |
|
4627 nm->fix_oop_relocations(); |
|
4628 } |
|
4629 } |
|
4630 } |
|
4631 }; |
|
4632 |
4583 class G1ParTask : public AbstractGangTask { |
4633 class G1ParTask : public AbstractGangTask { |
4584 protected: |
4634 protected: |
4585 G1CollectedHeap* _g1h; |
4635 G1CollectedHeap* _g1h; |
4586 RefToScanQueueSet *_queues; |
4636 RefToScanQueueSet *_queues; |
4587 ParallelTaskTerminator _terminator; |
4637 ParallelTaskTerminator _terminator; |
4643 |
4693 |
4644 } |
4694 } |
4645 |
4695 |
4646 void do_cld(ClassLoaderData* cld) { |
4696 void do_cld(ClassLoaderData* cld) { |
4647 cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim); |
4697 cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim); |
4648 } |
|
4649 }; |
|
4650 |
|
4651 class G1CodeBlobClosure: public CodeBlobClosure { |
|
4652 OopClosure* _f; |
|
4653 |
|
4654 public: |
|
4655 G1CodeBlobClosure(OopClosure* f) : _f(f) {} |
|
4656 void do_code_blob(CodeBlob* blob) { |
|
4657 nmethod* that = blob->as_nmethod_or_null(); |
|
4658 if (that != NULL) { |
|
4659 if (!that->test_set_oops_do_mark()) { |
|
4660 that->oops_do(_f); |
|
4661 that->fix_oop_relocations(); |
|
4662 } |
|
4663 } |
|
4664 } |
4698 } |
4665 }; |
4699 }; |
4666 |
4700 |
4667 void work(uint worker_id) { |
4701 void work(uint worker_id) { |
4668 if (worker_id >= _n_workers) return; // no work needed this round |
4702 if (worker_id >= _n_workers) return; // no work needed this round |
4852 } |
4886 } |
4853 } |
4887 } |
4854 g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms); |
4888 g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms); |
4855 |
4889 |
4856 // Now scan the complement of the collection set. |
4890 // Now scan the complement of the collection set. |
4857 MarkingCodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots, CodeBlobToOopClosure::FixRelocations); |
4891 G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); |
4858 |
4892 |
4859 g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); |
4893 g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); |
4860 |
4894 |
4861 _process_strong_tasks->all_tasks_completed(); |
4895 _process_strong_tasks->all_tasks_completed(); |
4862 } |
4896 } |
5898 // Reset and re-enable the hot card cache. |
5932 // Reset and re-enable the hot card cache. |
5899 // Note the counts for the cards in the regions in the |
5933 // Note the counts for the cards in the regions in the |
5900 // collection set are reset when the collection set is freed. |
5934 // collection set are reset when the collection set is freed. |
5901 hot_card_cache->reset_hot_cache(); |
5935 hot_card_cache->reset_hot_cache(); |
5902 hot_card_cache->set_use_cache(true); |
5936 hot_card_cache->set_use_cache(true); |
5903 |
|
5904 // Migrate the strong code roots attached to each region in |
|
5905 // the collection set. Ideally we would like to do this |
|
5906 // after we have finished the scanning/evacuation of the |
|
5907 // strong code roots for a particular heap region. |
|
5908 migrate_strong_code_roots(); |
|
5909 |
5937 |
5910 purge_code_root_memory(); |
5938 purge_code_root_memory(); |
5911 |
5939 |
5912 if (g1_policy()->during_initial_mark_pause()) { |
5940 if (g1_policy()->during_initial_mark_pause()) { |
5913 // Reset the claim values set during marking the strong code roots |
5941 // Reset the claim values set during marking the strong code roots |
6900 assert(!hr->continuesHumongous(), |
6928 assert(!hr->continuesHumongous(), |
6901 err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
6929 err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
6902 " starting at "HR_FORMAT, |
6930 " starting at "HR_FORMAT, |
6903 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
6931 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
6904 |
6932 |
6905 // HeapRegion::add_strong_code_root() avoids adding duplicate |
6933 // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries. |
6906 // entries but having duplicates is OK since we "mark" nmethods |
6934 hr->add_strong_code_root_locked(_nm); |
6907 // as visited when we scan the strong code root lists during the GC. |
|
6908 hr->add_strong_code_root(_nm); |
|
6909 assert(hr->rem_set()->strong_code_roots_list_contains(_nm), |
|
6910 err_msg("failed to add code root "PTR_FORMAT" to remembered set of region "HR_FORMAT, |
|
6911 _nm, HR_FORMAT_PARAMS(hr))); |
|
6912 } |
6935 } |
6913 } |
6936 } |
6914 |
6937 |
6915 public: |
6938 public: |
6916 RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
6939 RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
6933 err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
6956 err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT |
6934 " starting at "HR_FORMAT, |
6957 " starting at "HR_FORMAT, |
6935 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
6958 _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); |
6936 |
6959 |
6937 hr->remove_strong_code_root(_nm); |
6960 hr->remove_strong_code_root(_nm); |
6938 assert(!hr->rem_set()->strong_code_roots_list_contains(_nm), |
|
6939 err_msg("failed to remove code root "PTR_FORMAT" of region "HR_FORMAT, |
|
6940 _nm, HR_FORMAT_PARAMS(hr))); |
|
6941 } |
6961 } |
6942 } |
6962 } |
6943 |
6963 |
6944 public: |
6964 public: |
6945 UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
6965 UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : |
6963 guarantee(nm != NULL, "sanity"); |
6983 guarantee(nm != NULL, "sanity"); |
6964 UnregisterNMethodOopClosure reg_cl(this, nm); |
6984 UnregisterNMethodOopClosure reg_cl(this, nm); |
6965 nm->oops_do(®_cl, true); |
6985 nm->oops_do(®_cl, true); |
6966 } |
6986 } |
6967 |
6987 |
6968 class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure { |
|
6969 public: |
|
6970 bool doHeapRegion(HeapRegion *hr) { |
|
6971 assert(!hr->isHumongous(), |
|
6972 err_msg("humongous region "HR_FORMAT" should not have been added to collection set", |
|
6973 HR_FORMAT_PARAMS(hr))); |
|
6974 hr->migrate_strong_code_roots(); |
|
6975 return false; |
|
6976 } |
|
6977 }; |
|
6978 |
|
6979 void G1CollectedHeap::migrate_strong_code_roots() { |
|
6980 MigrateCodeRootsHeapRegionClosure cl; |
|
6981 double migrate_start = os::elapsedTime(); |
|
6982 collection_set_iterate(&cl); |
|
6983 double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0; |
|
6984 g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms); |
|
6985 } |
|
6986 |
|
6987 void G1CollectedHeap::purge_code_root_memory() { |
6988 void G1CollectedHeap::purge_code_root_memory() { |
6988 double purge_start = os::elapsedTime(); |
6989 double purge_start = os::elapsedTime(); |
6989 G1CodeRootSet::purge_chunks(G1CodeRootsChunkCacheKeepPercent); |
6990 G1CodeRootSet::purge(); |
6990 double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0; |
6991 double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0; |
6991 g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms); |
6992 g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms); |
6992 } |
6993 } |
6993 |
6994 |
6994 class RebuildStrongCodeRootClosure: public CodeBlobClosure { |
6995 class RebuildStrongCodeRootClosure: public CodeBlobClosure { |