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

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

*** 37,46 **** --- 37,47 ---- #include "gc_implementation/g1/g1GCPhaseTimes.hpp" #include "gc_implementation/g1/g1Log.hpp" #include "gc_implementation/g1/g1MarkSweep.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" + #include "gc_implementation/g1/g1StringDedup.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/vm_operations_g1.hpp"
*** 2171,2180 **** --- 2172,2183 ---- // Do create of the monitoring and management support so that // values in the heap have been properly initialized. _g1mm = new G1MonitoringSupport(this); + G1StringDedup::initialize(); + return JNI_OK; } size_t G1CollectedHeap::conservative_max_heap_alignment() { return HeapRegion::max_region_size();
*** 3455,3464 **** --- 3458,3472 ---- } } if (!silent) gclog_or_tty->print("RemSet "); rem_set()->verify(); + if (G1StringDedup::is_enabled()) { + if (!silent) gclog_or_tty->print("StrDedup "); + G1StringDedup::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().
*** 3472,3483 **** #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); --- 3480,3496 ---- #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 (G1StringDedup::is_enabled()) { ! gclog_or_tty->print(", StrDedup"); ! } ! gclog_or_tty->print(") "); ! } } } void G1CollectedHeap::verify(bool silent) { verify(silent, VerifyOption_G1UsePrevMarking);
*** 3566,3583 **** --- 3579,3602 ---- } _cmThread->print_on(st); st->cr(); _cm->print_worker_threads_on(st); _cg1r->print_worker_threads_on(st); + if (G1StringDedup::is_enabled()) { + G1StringDedup::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); + if (G1StringDedup::is_enabled()) { + G1StringDedup::threads_do(tc); + } } void G1CollectedHeap::print_tracing_info() const { // We'll overload this to mean "trace GC pause statistics." if (TraceGen0Time || TraceGen1Time) {
*** 4754,4763 **** --- 4773,4789 ---- age_table()->add(obj, word_sz); } else { obj->set_mark(m); } + if (G1StringDedup::is_enabled()) { + G1StringDedup::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
*** 5217,5226 **** --- 5243,5256 ---- "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, " "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed", g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(), g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed()); } + + if (G1StringDedup::is_enabled()) { + G1StringDedup::unlink(is_alive); + } } class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { public: bool do_card_ptr(jbyte* card_ptr, int worker_i) {
*** 5840,5849 **** --- 5870,5882 ---- // Weak root processing. { G1STWIsAliveClosure is_alive(this); G1KeepAliveClosure keep_alive(this); JNIHandles::weak_oops_do(&is_alive, &keep_alive); + if (G1StringDedup::is_enabled()) { + G1StringDedup::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();
*** 6320,6332 **** 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 { --- 6353,6366 ---- 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 {
*** 6376,6385 **** --- 6410,6423 ---- }; 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();