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) { |