comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 17764:595c0f60d50d

8029075: String deduplication in G1 Summary: Implementation of JEP 192, http://openjdk.java.net/jeps/192 Reviewed-by: brutisso, tschatzl, coleenp
author pliden
date Tue, 18 Mar 2014 19:07:22 +0100
parents bc22cbb8b45a
children 2775f322649a
comparison
equal deleted inserted replaced
17763:6e7e363c5a8f 17764:595c0f60d50d
37 #include "gc_implementation/g1/g1GCPhaseTimes.hpp" 37 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
38 #include "gc_implementation/g1/g1Log.hpp" 38 #include "gc_implementation/g1/g1Log.hpp"
39 #include "gc_implementation/g1/g1MarkSweep.hpp" 39 #include "gc_implementation/g1/g1MarkSweep.hpp"
40 #include "gc_implementation/g1/g1OopClosures.inline.hpp" 40 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
41 #include "gc_implementation/g1/g1RemSet.inline.hpp" 41 #include "gc_implementation/g1/g1RemSet.inline.hpp"
42 #include "gc_implementation/g1/g1StringDedup.hpp"
42 #include "gc_implementation/g1/g1YCTypes.hpp" 43 #include "gc_implementation/g1/g1YCTypes.hpp"
43 #include "gc_implementation/g1/heapRegion.inline.hpp" 44 #include "gc_implementation/g1/heapRegion.inline.hpp"
44 #include "gc_implementation/g1/heapRegionRemSet.hpp" 45 #include "gc_implementation/g1/heapRegionRemSet.hpp"
45 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" 46 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
46 #include "gc_implementation/g1/vm_operations_g1.hpp" 47 #include "gc_implementation/g1/vm_operations_g1.hpp"
2171 2172
2172 // Do create of the monitoring and management support so that 2173 // Do create of the monitoring and management support so that
2173 // values in the heap have been properly initialized. 2174 // values in the heap have been properly initialized.
2174 _g1mm = new G1MonitoringSupport(this); 2175 _g1mm = new G1MonitoringSupport(this);
2175 2176
2177 G1StringDedup::initialize();
2178
2176 return JNI_OK; 2179 return JNI_OK;
2177 } 2180 }
2178 2181
2179 size_t G1CollectedHeap::conservative_max_heap_alignment() { 2182 size_t G1CollectedHeap::conservative_max_heap_alignment() {
2180 return HeapRegion::max_region_size(); 2183 return HeapRegion::max_region_size();
3473 } 3476 }
3474 } 3477 }
3475 if (!silent) gclog_or_tty->print("RemSet "); 3478 if (!silent) gclog_or_tty->print("RemSet ");
3476 rem_set()->verify(); 3479 rem_set()->verify();
3477 3480
3481 if (G1StringDedup::is_enabled()) {
3482 if (!silent) gclog_or_tty->print("StrDedup ");
3483 G1StringDedup::verify();
3484 }
3485
3478 if (failures) { 3486 if (failures) {
3479 gclog_or_tty->print_cr("Heap:"); 3487 gclog_or_tty->print_cr("Heap:");
3480 // It helps to have the per-region information in the output to 3488 // It helps to have the per-region information in the output to
3481 // help us track down what went wrong. This is why we call 3489 // help us track down what went wrong. This is why we call
3482 // print_extended_on() instead of print_on(). 3490 // print_extended_on() instead of print_on().
3490 #endif 3498 #endif
3491 gclog_or_tty->flush(); 3499 gclog_or_tty->flush();
3492 } 3500 }
3493 guarantee(!failures, "there should not have been any failures"); 3501 guarantee(!failures, "there should not have been any failures");
3494 } else { 3502 } else {
3495 if (!silent) 3503 if (!silent) {
3496 gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); 3504 gclog_or_tty->print("(SKIPPING Roots, HeapRegionSets, HeapRegions, RemSet");
3505 if (G1StringDedup::is_enabled()) {
3506 gclog_or_tty->print(", StrDedup");
3507 }
3508 gclog_or_tty->print(") ");
3509 }
3497 } 3510 }
3498 } 3511 }
3499 3512
3500 void G1CollectedHeap::verify(bool silent) { 3513 void G1CollectedHeap::verify(bool silent) {
3501 verify(silent, VerifyOption_G1UsePrevMarking); 3514 verify(silent, VerifyOption_G1UsePrevMarking);
3584 } 3597 }
3585 _cmThread->print_on(st); 3598 _cmThread->print_on(st);
3586 st->cr(); 3599 st->cr();
3587 _cm->print_worker_threads_on(st); 3600 _cm->print_worker_threads_on(st);
3588 _cg1r->print_worker_threads_on(st); 3601 _cg1r->print_worker_threads_on(st);
3602 if (G1StringDedup::is_enabled()) {
3603 G1StringDedup::print_worker_threads_on(st);
3604 }
3589 } 3605 }
3590 3606
3591 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { 3607 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
3592 if (G1CollectedHeap::use_parallel_gc_threads()) { 3608 if (G1CollectedHeap::use_parallel_gc_threads()) {
3593 workers()->threads_do(tc); 3609 workers()->threads_do(tc);
3594 } 3610 }
3595 tc->do_thread(_cmThread); 3611 tc->do_thread(_cmThread);
3596 _cg1r->threads_do(tc); 3612 _cg1r->threads_do(tc);
3613 if (G1StringDedup::is_enabled()) {
3614 G1StringDedup::threads_do(tc);
3615 }
3597 } 3616 }
3598 3617
3599 void G1CollectedHeap::print_tracing_info() const { 3618 void G1CollectedHeap::print_tracing_info() const {
3600 // We'll overload this to mean "trace GC pause statistics." 3619 // We'll overload this to mean "trace GC pause statistics."
3601 if (TraceGen0Time || TraceGen1Time) { 3620 if (TraceGen0Time || TraceGen1Time) {
4772 age_table()->add(obj, word_sz); 4791 age_table()->add(obj, word_sz);
4773 } else { 4792 } else {
4774 obj->set_mark(m); 4793 obj->set_mark(m);
4775 } 4794 }
4776 4795
4796 if (G1StringDedup::is_enabled()) {
4797 G1StringDedup::enqueue_from_evacuation(from_region->is_young(),
4798 to_region->is_young(),
4799 queue_num(),
4800 obj);
4801 }
4802
4777 size_t* surv_young_words = surviving_young_words(); 4803 size_t* surv_young_words = surviving_young_words();
4778 surv_young_words[young_index] += word_sz; 4804 surv_young_words[young_index] += word_sz;
4779 4805
4780 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 4806 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
4781 // We keep track of the next start index in the length field of 4807 // We keep track of the next start index in the length field of
5247 "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, " 5273 "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
5248 "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed", 5274 "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
5249 g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(), 5275 g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(),
5250 g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed()); 5276 g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed());
5251 } 5277 }
5278
5279 if (G1StringDedup::is_enabled()) {
5280 G1StringDedup::unlink(is_alive);
5281 }
5252 } 5282 }
5253 5283
5254 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { 5284 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure {
5255 public: 5285 public:
5256 bool do_card_ptr(jbyte* card_ptr, int worker_i) { 5286 bool do_card_ptr(jbyte* card_ptr, int worker_i) {
5870 // Weak root processing. 5900 // Weak root processing.
5871 { 5901 {
5872 G1STWIsAliveClosure is_alive(this); 5902 G1STWIsAliveClosure is_alive(this);
5873 G1KeepAliveClosure keep_alive(this); 5903 G1KeepAliveClosure keep_alive(this);
5874 JNIHandles::weak_oops_do(&is_alive, &keep_alive); 5904 JNIHandles::weak_oops_do(&is_alive, &keep_alive);
5905 if (G1StringDedup::is_enabled()) {
5906 G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive);
5907 }
5875 } 5908 }
5876 5909
5877 release_gc_alloc_regions(n_workers, evacuation_info); 5910 release_gc_alloc_regions(n_workers, evacuation_info);
5878 g1_rem_set()->cleanup_after_oops_into_collection_set_do(); 5911 g1_rem_set()->cleanup_after_oops_into_collection_set_do();
5879 5912
6350 6383
6351 if (!free_list_only) { 6384 if (!free_list_only) {
6352 TearDownRegionSetsClosure cl(&_old_set); 6385 TearDownRegionSetsClosure cl(&_old_set);
6353 heap_region_iterate(&cl); 6386 heap_region_iterate(&cl);
6354 6387
6355 // Need to do this after the heap iteration to be able to 6388 // Note that emptying the _young_list is postponed and instead done as
6356 // recognize the young regions and ignore them during the iteration. 6389 // the first step when rebuilding the regions sets again. The reason for
6357 _young_list->empty_list(); 6390 // this is that during a full GC string deduplication needs to know if
6391 // a collected region was young or old when the full GC was initiated.
6358 } 6392 }
6359 _free_list.remove_all(); 6393 _free_list.remove_all();
6360 } 6394 }
6361 6395
6362 class RebuildRegionSetsClosure : public HeapRegionClosure { 6396 class RebuildRegionSetsClosure : public HeapRegionClosure {
6405 } 6439 }
6406 }; 6440 };
6407 6441
6408 void G1CollectedHeap::rebuild_region_sets(bool free_list_only) { 6442 void G1CollectedHeap::rebuild_region_sets(bool free_list_only) {
6409 assert_at_safepoint(true /* should_be_vm_thread */); 6443 assert_at_safepoint(true /* should_be_vm_thread */);
6444
6445 if (!free_list_only) {
6446 _young_list->empty_list();
6447 }
6410 6448
6411 RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list); 6449 RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list);
6412 heap_region_iterate(&cl); 6450 heap_region_iterate(&cl);
6413 6451
6414 if (!free_list_only) { 6452 if (!free_list_only) {