--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 18 09:57:47 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 23 23:56:15 2009 -0700
@@ -25,6 +25,8 @@
#include "incls/_precompiled.incl"
#include "incls/_g1CollectedHeap.cpp.incl"
+size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
+
// turn it on so that the contents of the young list (scan-only /
// to-be-collected) are printed at "strategic" points before / during
// / after the collection --- this is useful for debugging
@@ -927,7 +929,6 @@
TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
double start = os::elapsedTime();
- GCOverheadReporter::recordSTWStart(start);
g1_policy()->record_full_collection_start();
gc_prologue(true);
@@ -1049,7 +1050,6 @@
}
double end = os::elapsedTime();
- GCOverheadReporter::recordSTWEnd(end);
g1_policy()->record_full_collection_end();
#ifdef TRACESPINNING
@@ -1396,6 +1396,9 @@
if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
vm_exit_during_initialization("Failed necessary allocation.");
}
+
+ _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
+
int n_queues = MAX2((int)ParallelGCThreads, 1);
_task_queues = new RefToScanQueueSet(n_queues);
@@ -1548,9 +1551,10 @@
const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
- const size_t cards_per_region = HeapRegion::GrainBytes >> CardTableModRefBS::card_shift;
size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
- guarantee(cards_per_region < max_cards_per_region, "too many cards per region");
+ guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized");
+ guarantee((size_t) HeapRegion::CardsPerRegion < max_cards_per_region,
+ "too many cards per region");
_bot_shared = new G1BlockOffsetSharedArray(_reserved,
heap_word_size(init_byte_size));
@@ -1610,9 +1614,6 @@
// Do later initialization work for concurrent refinement.
_cg1r->init();
- const char* group_names[] = { "CR", "ZF", "CM", "CL" };
- GCOverheadReporter::initGCOverheadReporter(4, group_names);
-
return JNI_OK;
}
@@ -2434,8 +2435,6 @@
}
g1_policy()->print_yg_surv_rate_info();
- GCOverheadReporter::printGCOverhead();
-
SpecializationStats::print();
}
@@ -2672,7 +2671,6 @@
// The elapsed time induced by the start time below deliberately elides
// the possible verification above.
double start_time_sec = os::elapsedTime();
- GCOverheadReporter::recordSTWStart(start_time_sec);
size_t start_used_bytes = used();
g1_policy()->record_collection_pause_start(start_time_sec,
@@ -2750,8 +2748,6 @@
_in_cset_fast_test = NULL;
_in_cset_fast_test_base = NULL;
- release_gc_alloc_regions(false /* totally */);
-
cleanup_surviving_young_words();
if (g1_policy()->in_young_gc_mode()) {
@@ -2801,7 +2797,6 @@
double end_time_sec = os::elapsedTime();
double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
g1_policy()->record_pause_time_ms(pause_time_ms);
- GCOverheadReporter::recordSTWEnd(end_time_sec);
g1_policy()->record_collection_pause_end(abandoned);
assert(regions_accounted_for(), "Region leakage.");
@@ -4152,6 +4147,7 @@
G1KeepAliveClosure keep_alive(this);
JNIHandles::weak_oops_do(&is_alive, &keep_alive);
}
+ release_gc_alloc_regions(false /* totally */);
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
concurrent_g1_refine()->clear_hot_cache();
@@ -4285,12 +4281,18 @@
class G1ParCleanupCTTask : public AbstractGangTask {
CardTableModRefBS* _ct_bs;
G1CollectedHeap* _g1h;
+ HeapRegion* volatile _so_head;
+ HeapRegion* volatile _su_head;
public:
G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
- G1CollectedHeap* g1h) :
+ G1CollectedHeap* g1h,
+ HeapRegion* scan_only_list,
+ HeapRegion* survivor_list) :
AbstractGangTask("G1 Par Cleanup CT Task"),
_ct_bs(ct_bs),
- _g1h(g1h)
+ _g1h(g1h),
+ _so_head(scan_only_list),
+ _su_head(survivor_list)
{ }
void work(int i) {
@@ -4298,22 +4300,64 @@
while (r = _g1h->pop_dirty_cards_region()) {
clear_cards(r);
}
- }
+ // Redirty the cards of the scan-only and survivor regions.
+ dirty_list(&this->_so_head);
+ dirty_list(&this->_su_head);
+ }
+
void clear_cards(HeapRegion* r) {
// Cards for Survivor and Scan-Only regions will be dirtied later.
if (!r->is_scan_only() && !r->is_survivor()) {
_ct_bs->clear(MemRegion(r->bottom(), r->end()));
}
}
+
+ void dirty_list(HeapRegion* volatile * head_ptr) {
+ HeapRegion* head;
+ do {
+ // Pop region off the list.
+ head = *head_ptr;
+ if (head != NULL) {
+ HeapRegion* r = (HeapRegion*)
+ Atomic::cmpxchg_ptr(head->get_next_young_region(), head_ptr, head);
+ if (r == head) {
+ assert(!r->isHumongous(), "Humongous regions shouldn't be on survivor list");
+ _ct_bs->dirty(MemRegion(r->bottom(), r->end()));
+ }
+ }
+ } while (*head_ptr != NULL);
+ }
};
+#ifndef PRODUCT
+class G1VerifyCardTableCleanup: public HeapRegionClosure {
+ CardTableModRefBS* _ct_bs;
+public:
+ G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs)
+ : _ct_bs(ct_bs)
+ { }
+ virtual bool doHeapRegion(HeapRegion* r)
+ {
+ MemRegion mr(r->bottom(), r->end());
+ if (r->is_scan_only() || r->is_survivor()) {
+ _ct_bs->verify_dirty_region(mr);
+ } else {
+ _ct_bs->verify_clean_region(mr);
+ }
+ return false;
+ }
+};
+#endif
+
void G1CollectedHeap::cleanUpCardTable() {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
double start = os::elapsedTime();
// Iterate over the dirty cards region list.
- G1ParCleanupCTTask cleanup_task(ct_bs, this);
+ G1ParCleanupCTTask cleanup_task(ct_bs, this,
+ _young_list->first_scan_only_region(),
+ _young_list->first_survivor_region());
if (ParallelGCThreads > 0) {
set_par_threads(workers()->total_workers());
workers()->run_task(&cleanup_task);
@@ -4329,18 +4373,22 @@
}
r->set_next_dirty_cards_region(NULL);
}
- }
- // now, redirty the cards of the scan-only and survivor regions
- // (it seemed faster to do it this way, instead of iterating over
- // all regions and then clearing / dirtying as appropriate)
- dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region());
- dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region());
-
+ // now, redirty the cards of the scan-only and survivor regions
+ // (it seemed faster to do it this way, instead of iterating over
+ // all regions and then clearing / dirtying as appropriate)
+ dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region());
+ dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region());
+ }
double elapsed = os::elapsedTime() - start;
g1_policy()->record_clear_ct_time( elapsed * 1000.0);
+#ifndef PRODUCT
+ if (G1VerifyCTCleanup || VerifyAfterGC) {
+ G1VerifyCardTableCleanup cleanup_verifier(ct_bs);
+ heap_region_iterate(&cleanup_verifier);
+ }
+#endif
}
-
void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) {
if (g1_policy()->should_do_collection_pause(word_size)) {
do_collection_pause();
@@ -5033,7 +5081,7 @@
return hr->is_in(p);
}
}
-#endif // PRODUCT
+#endif // !PRODUCT
void G1CollectedHeap::g1_unimplemented() {
// Unimplemented();