src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

changeset 1428
54b3b351d6f9
parent 1424
148e5441d916
parent 1377
2c79770d1f6e
child 1454
035d2e036a9b
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Sep 18 09:57:47 2009 -0700
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Sep 23 23:56:15 2009 -0700
     1.3 @@ -25,6 +25,8 @@
     1.4  #include "incls/_precompiled.incl"
     1.5  #include "incls/_g1CollectedHeap.cpp.incl"
     1.6  
     1.7 +size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
     1.8 +
     1.9  // turn it on so that the contents of the young list (scan-only /
    1.10  // to-be-collected) are printed at "strategic" points before / during
    1.11  // / after the collection --- this is useful for debugging
    1.12 @@ -927,7 +929,6 @@
    1.13      TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
    1.14  
    1.15      double start = os::elapsedTime();
    1.16 -    GCOverheadReporter::recordSTWStart(start);
    1.17      g1_policy()->record_full_collection_start();
    1.18  
    1.19      gc_prologue(true);
    1.20 @@ -1049,7 +1050,6 @@
    1.21      }
    1.22  
    1.23      double end = os::elapsedTime();
    1.24 -    GCOverheadReporter::recordSTWEnd(end);
    1.25      g1_policy()->record_full_collection_end();
    1.26  
    1.27  #ifdef TRACESPINNING
    1.28 @@ -1396,6 +1396,9 @@
    1.29    if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
    1.30      vm_exit_during_initialization("Failed necessary allocation.");
    1.31    }
    1.32 +
    1.33 +  _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
    1.34 +
    1.35    int n_queues = MAX2((int)ParallelGCThreads, 1);
    1.36    _task_queues = new RefToScanQueueSet(n_queues);
    1.37  
    1.38 @@ -1548,9 +1551,10 @@
    1.39    const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
    1.40    guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
    1.41  
    1.42 -  const size_t cards_per_region = HeapRegion::GrainBytes >> CardTableModRefBS::card_shift;
    1.43    size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
    1.44 -  guarantee(cards_per_region < max_cards_per_region, "too many cards per region");
    1.45 +  guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized");
    1.46 +  guarantee((size_t) HeapRegion::CardsPerRegion < max_cards_per_region,
    1.47 +            "too many cards per region");
    1.48  
    1.49    _bot_shared = new G1BlockOffsetSharedArray(_reserved,
    1.50                                               heap_word_size(init_byte_size));
    1.51 @@ -1610,9 +1614,6 @@
    1.52    // Do later initialization work for concurrent refinement.
    1.53    _cg1r->init();
    1.54  
    1.55 -  const char* group_names[] = { "CR", "ZF", "CM", "CL" };
    1.56 -  GCOverheadReporter::initGCOverheadReporter(4, group_names);
    1.57 -
    1.58    return JNI_OK;
    1.59  }
    1.60  
    1.61 @@ -2434,8 +2435,6 @@
    1.62    }
    1.63    g1_policy()->print_yg_surv_rate_info();
    1.64  
    1.65 -  GCOverheadReporter::printGCOverhead();
    1.66 -
    1.67    SpecializationStats::print();
    1.68  }
    1.69  
    1.70 @@ -2672,7 +2671,6 @@
    1.71        // The elapsed time induced by the start time below deliberately elides
    1.72        // the possible verification above.
    1.73        double start_time_sec = os::elapsedTime();
    1.74 -      GCOverheadReporter::recordSTWStart(start_time_sec);
    1.75        size_t start_used_bytes = used();
    1.76  
    1.77        g1_policy()->record_collection_pause_start(start_time_sec,
    1.78 @@ -2750,8 +2748,6 @@
    1.79          _in_cset_fast_test = NULL;
    1.80          _in_cset_fast_test_base = NULL;
    1.81  
    1.82 -        release_gc_alloc_regions(false /* totally */);
    1.83 -
    1.84          cleanup_surviving_young_words();
    1.85  
    1.86          if (g1_policy()->in_young_gc_mode()) {
    1.87 @@ -2801,7 +2797,6 @@
    1.88        double end_time_sec = os::elapsedTime();
    1.89        double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
    1.90        g1_policy()->record_pause_time_ms(pause_time_ms);
    1.91 -      GCOverheadReporter::recordSTWEnd(end_time_sec);
    1.92        g1_policy()->record_collection_pause_end(abandoned);
    1.93  
    1.94        assert(regions_accounted_for(), "Region leakage.");
    1.95 @@ -4152,6 +4147,7 @@
    1.96      G1KeepAliveClosure keep_alive(this);
    1.97      JNIHandles::weak_oops_do(&is_alive, &keep_alive);
    1.98    }
    1.99 +  release_gc_alloc_regions(false /* totally */);
   1.100    g1_rem_set()->cleanup_after_oops_into_collection_set_do();
   1.101  
   1.102    concurrent_g1_refine()->clear_hot_cache();
   1.103 @@ -4285,12 +4281,18 @@
   1.104  class G1ParCleanupCTTask : public AbstractGangTask {
   1.105    CardTableModRefBS* _ct_bs;
   1.106    G1CollectedHeap* _g1h;
   1.107 +  HeapRegion* volatile _so_head;
   1.108 +  HeapRegion* volatile _su_head;
   1.109  public:
   1.110    G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
   1.111 -                     G1CollectedHeap* g1h) :
   1.112 +                     G1CollectedHeap* g1h,
   1.113 +                     HeapRegion* scan_only_list,
   1.114 +                     HeapRegion* survivor_list) :
   1.115      AbstractGangTask("G1 Par Cleanup CT Task"),
   1.116      _ct_bs(ct_bs),
   1.117 -    _g1h(g1h)
   1.118 +    _g1h(g1h),
   1.119 +    _so_head(scan_only_list),
   1.120 +    _su_head(survivor_list)
   1.121    { }
   1.122  
   1.123    void work(int i) {
   1.124 @@ -4298,22 +4300,64 @@
   1.125      while (r = _g1h->pop_dirty_cards_region()) {
   1.126        clear_cards(r);
   1.127      }
   1.128 -  }
   1.129 +    // Redirty the cards of the scan-only and survivor regions.
   1.130 +    dirty_list(&this->_so_head);
   1.131 +    dirty_list(&this->_su_head);
   1.132 +  }
   1.133 +
   1.134    void clear_cards(HeapRegion* r) {
   1.135      // Cards for Survivor and Scan-Only regions will be dirtied later.
   1.136      if (!r->is_scan_only() && !r->is_survivor()) {
   1.137        _ct_bs->clear(MemRegion(r->bottom(), r->end()));
   1.138      }
   1.139    }
   1.140 +
   1.141 +  void dirty_list(HeapRegion* volatile * head_ptr) {
   1.142 +    HeapRegion* head;
   1.143 +    do {
   1.144 +      // Pop region off the list.
   1.145 +      head = *head_ptr;
   1.146 +      if (head != NULL) {
   1.147 +        HeapRegion* r = (HeapRegion*)
   1.148 +          Atomic::cmpxchg_ptr(head->get_next_young_region(), head_ptr, head);
   1.149 +        if (r == head) {
   1.150 +          assert(!r->isHumongous(), "Humongous regions shouldn't be on survivor list");
   1.151 +          _ct_bs->dirty(MemRegion(r->bottom(), r->end()));
   1.152 +        }
   1.153 +      }
   1.154 +    } while (*head_ptr != NULL);
   1.155 +  }
   1.156  };
   1.157  
   1.158  
   1.159 +#ifndef PRODUCT
   1.160 +class G1VerifyCardTableCleanup: public HeapRegionClosure {
   1.161 +  CardTableModRefBS* _ct_bs;
   1.162 +public:
   1.163 +  G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs)
   1.164 +    : _ct_bs(ct_bs)
   1.165 +  { }
   1.166 +  virtual bool doHeapRegion(HeapRegion* r)
   1.167 +  {
   1.168 +    MemRegion mr(r->bottom(), r->end());
   1.169 +    if (r->is_scan_only() || r->is_survivor()) {
   1.170 +      _ct_bs->verify_dirty_region(mr);
   1.171 +    } else {
   1.172 +      _ct_bs->verify_clean_region(mr);
   1.173 +    }
   1.174 +    return false;
   1.175 +  }
   1.176 +};
   1.177 +#endif
   1.178 +
   1.179  void G1CollectedHeap::cleanUpCardTable() {
   1.180    CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
   1.181    double start = os::elapsedTime();
   1.182  
   1.183    // Iterate over the dirty cards region list.
   1.184 -  G1ParCleanupCTTask cleanup_task(ct_bs, this);
   1.185 +  G1ParCleanupCTTask cleanup_task(ct_bs, this,
   1.186 +                                  _young_list->first_scan_only_region(),
   1.187 +                                  _young_list->first_survivor_region());
   1.188    if (ParallelGCThreads > 0) {
   1.189      set_par_threads(workers()->total_workers());
   1.190      workers()->run_task(&cleanup_task);
   1.191 @@ -4329,18 +4373,22 @@
   1.192        }
   1.193        r->set_next_dirty_cards_region(NULL);
   1.194      }
   1.195 -  }
   1.196 -  // now, redirty the cards of the scan-only and survivor regions
   1.197 -  // (it seemed faster to do it this way, instead of iterating over
   1.198 -  // all regions and then clearing / dirtying as appropriate)
   1.199 -  dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region());
   1.200 -  dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region());
   1.201 -
   1.202 +    // now, redirty the cards of the scan-only and survivor regions
   1.203 +    // (it seemed faster to do it this way, instead of iterating over
   1.204 +    // all regions and then clearing / dirtying as appropriate)
   1.205 +    dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region());
   1.206 +    dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region());
   1.207 +  }
   1.208    double elapsed = os::elapsedTime() - start;
   1.209    g1_policy()->record_clear_ct_time( elapsed * 1000.0);
   1.210 +#ifndef PRODUCT
   1.211 +  if (G1VerifyCTCleanup || VerifyAfterGC) {
   1.212 +    G1VerifyCardTableCleanup cleanup_verifier(ct_bs);
   1.213 +    heap_region_iterate(&cleanup_verifier);
   1.214 +  }
   1.215 +#endif
   1.216  }
   1.217  
   1.218 -
   1.219  void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) {
   1.220    if (g1_policy()->should_do_collection_pause(word_size)) {
   1.221      do_collection_pause();
   1.222 @@ -5033,7 +5081,7 @@
   1.223      return hr->is_in(p);
   1.224    }
   1.225  }
   1.226 -#endif // PRODUCT
   1.227 +#endif // !PRODUCT
   1.228  
   1.229  void G1CollectedHeap::g1_unimplemented() {
   1.230    // Unimplemented();

mercurial