--- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-03-07 14:31:29.827542221 +0100 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-03-07 14:31:29.686562602 +0100 @@ -43,6 +43,7 @@ #include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/stringDedup.hpp" #include "gc_implementation/g1/vm_operations_g1.hpp" #include "gc_implementation/shared/gcHeapSummary.hpp" #include "gc_implementation/shared/gcTimer.hpp" @@ -2182,6 +2183,8 @@ // values in the heap have been properly initialized. _g1mm = new G1MonitoringSupport(this); + StringDedup::initialize(); + return JNI_OK; } @@ -3462,6 +3465,11 @@ if (!silent) gclog_or_tty->print("RemSet "); rem_set()->verify(); + if (UseStringDeduplication) { + if (!silent) gclog_or_tty->print("StrDedup "); + StringDedup::verify(); + } + if (failures) { gclog_or_tty->print_cr("Heap:"); // It helps to have the per-region information in the output to @@ -3479,8 +3487,13 @@ } guarantee(!failures, "there should not have been any failures"); } else { - if (!silent) - gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); + if (!silent) { + gclog_or_tty->print("(SKIPPING Roots, HeapRegionSets, HeapRegions, RemSet"); + if (UseStringDeduplication) { + gclog_or_tty->print(", StrDedup"); + } + gclog_or_tty->print(") "); + } } } @@ -3573,6 +3586,7 @@ st->cr(); _cm->print_worker_threads_on(st); _cg1r->print_worker_threads_on(st); + StringDedup::print_worker_threads_on(st); } void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { @@ -3581,6 +3595,7 @@ } tc->do_thread(_cmThread); _cg1r->threads_do(tc); + StringDedup::threads_do(tc); } void G1CollectedHeap::print_tracing_info() const { @@ -4760,6 +4775,13 @@ obj->set_mark(m); } + if (UseStringDeduplication) { + StringDedup::enqueue_from_evacuation(from_region->is_young(), + to_region->is_young(), + queue_num(), + obj); + } + size_t* surv_young_words = surviving_young_words(); surv_young_words[young_index] += word_sz; @@ -5889,6 +5911,7 @@ G1STWIsAliveClosure is_alive(this); G1KeepAliveClosure keep_alive(this); JNIHandles::weak_oops_do(&is_alive, &keep_alive); + StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); } release_gc_alloc_regions(n_workers, evacuation_info); @@ -6408,9 +6431,10 @@ TearDownRegionSetsClosure cl(&_old_set); heap_region_iterate(&cl); - // Need to do this after the heap iteration to be able to - // recognize the young regions and ignore them during the iteration. - _young_list->empty_list(); + // Note that emptying the _young_list is postponed and instead done as + // the first step when rebuilding the regions sets again. The reason for + // this is that during a full GC string deduplication needs to know if + // a collected region was young or old when the full GC was initiated. } _free_list.remove_all(); } @@ -6464,6 +6488,10 @@ void G1CollectedHeap::rebuild_region_sets(bool free_list_only) { assert_at_safepoint(true /* should_be_vm_thread */); + if (!free_list_only) { + _young_list->empty_list(); + } + RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list); heap_region_iterate(&cl);