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();