hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
changeset 26422 4ee5901e205e
parent 26316 93f6b40c038b
child 26692 b24a4cc794ce
child 26796 666464578742
equal deleted inserted replaced
26421:37d88e604ad0 26422:4ee5901e205e
  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(&reg_cl, true);
  7132   nm->oops_do(&reg_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 {