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

Print this page
rev 6069 : 8029075: String deduplication in G1
Implementation of JEP 192, http://openjdk.java.net/jeps/192

*** 41,50 **** --- 41,51 ---- #include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1YCTypes.hpp" #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" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcTraceTime.hpp"
*** 2180,2189 **** --- 2181,2192 ---- // Do create of the monitoring and management support so that // values in the heap have been properly initialized. _g1mm = new G1MonitoringSupport(this); + StringDedup::initialize(); + return JNI_OK; } size_t G1CollectedHeap::conservative_max_heap_alignment() { return HeapRegion::max_region_size();
*** 3460,3469 **** --- 3463,3477 ---- } } 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 // help us track down what went wrong. This is why we call // print_extended_on() instead of print_on().
*** 3477,3488 **** #endif gclog_or_tty->flush(); } guarantee(!failures, "there should not have been any failures"); } else { ! if (!silent) ! gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); } } void G1CollectedHeap::verify(bool silent) { verify(silent, VerifyOption_G1UsePrevMarking); --- 3485,3501 ---- #endif gclog_or_tty->flush(); } guarantee(!failures, "there should not have been any failures"); } else { ! if (!silent) { ! gclog_or_tty->print("(SKIPPING Roots, HeapRegionSets, HeapRegions, RemSet"); ! if (UseStringDeduplication) { ! gclog_or_tty->print(", StrDedup"); ! } ! gclog_or_tty->print(") "); ! } } } void G1CollectedHeap::verify(bool silent) { verify(silent, VerifyOption_G1UsePrevMarking);
*** 3571,3588 **** --- 3584,3603 ---- } _cmThread->print_on(st); 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 { if (G1CollectedHeap::use_parallel_gc_threads()) { workers()->threads_do(tc); } tc->do_thread(_cmThread); _cg1r->threads_do(tc); + StringDedup::threads_do(tc); } void G1CollectedHeap::print_tracing_info() const { // We'll overload this to mean "trace GC pause statistics." if (TraceGen0Time || TraceGen1Time) {
*** 4758,4767 **** --- 4773,4789 ---- age_table()->add(obj, word_sz); } else { 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; if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { // We keep track of the next start index in the length field of
*** 5887,5896 **** --- 5909,5919 ---- // Weak root processing. { 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); g1_rem_set()->cleanup_after_oops_into_collection_set_do();
*** 6406,6418 **** if (!free_list_only) { 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(); } _free_list.remove_all(); } class RebuildRegionSetsClosure : public HeapRegionClosure { --- 6429,6442 ---- if (!free_list_only) { TearDownRegionSetsClosure cl(&_old_set); heap_region_iterate(&cl); ! // 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(); } class RebuildRegionSetsClosure : public HeapRegionClosure {
*** 6462,6471 **** --- 6486,6499 ---- }; 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); if (!free_list_only) { _summary_bytes_used = cl.total_used();