Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @ 10405:f2110083203d
8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
author | sla |
---|---|
date | Mon, 10 Jun 2013 11:30:51 +0200 |
parents | a30e7b564541 |
children | 330dfb0476f4 |
comparison
equal
deleted
inserted
replaced
10404:d0add7016434 | 10405:f2110083203d |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
27 #include "gc_implementation/parNew/parNewGeneration.hpp" | 27 #include "gc_implementation/parNew/parNewGeneration.hpp" |
28 #include "gc_implementation/parNew/parOopClosures.inline.hpp" | 28 #include "gc_implementation/parNew/parOopClosures.inline.hpp" |
29 #include "gc_implementation/shared/adaptiveSizePolicy.hpp" | 29 #include "gc_implementation/shared/adaptiveSizePolicy.hpp" |
30 #include "gc_implementation/shared/ageTable.hpp" | 30 #include "gc_implementation/shared/ageTable.hpp" |
31 #include "gc_implementation/shared/parGCAllocBuffer.hpp" | 31 #include "gc_implementation/shared/parGCAllocBuffer.hpp" |
32 #include "gc_implementation/shared/gcHeapSummary.hpp" | |
33 #include "gc_implementation/shared/gcTimer.hpp" | |
34 #include "gc_implementation/shared/gcTrace.hpp" | |
35 #include "gc_implementation/shared/gcTraceTime.hpp" | |
36 #include "gc_implementation/shared/copyFailedInfo.hpp" | |
32 #include "gc_implementation/shared/spaceDecorator.hpp" | 37 #include "gc_implementation/shared/spaceDecorator.hpp" |
33 #include "memory/defNewGeneration.inline.hpp" | 38 #include "memory/defNewGeneration.inline.hpp" |
34 #include "memory/genCollectedHeap.hpp" | 39 #include "memory/genCollectedHeap.hpp" |
35 #include "memory/genOopClosures.inline.hpp" | 40 #include "memory/genOopClosures.inline.hpp" |
36 #include "memory/generation.hpp" | 41 #include "memory/generation.hpp" |
73 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure, | 78 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure, |
74 &_to_space_root_closure, gen_, &_old_gen_root_closure, | 79 &_to_space_root_closure, gen_, &_old_gen_root_closure, |
75 work_queue_set_, &term_), | 80 work_queue_set_, &term_), |
76 _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this), | 81 _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this), |
77 _keep_alive_closure(&_scan_weak_ref_closure), | 82 _keep_alive_closure(&_scan_weak_ref_closure), |
78 _promotion_failure_size(0), | |
79 _strong_roots_time(0.0), _term_time(0.0) | 83 _strong_roots_time(0.0), _term_time(0.0) |
80 { | 84 { |
81 #if TASKQUEUE_STATS | 85 #if TASKQUEUE_STATS |
82 _term_attempts = 0; | 86 _term_attempts = 0; |
83 _overflow_refills = 0; | 87 _overflow_refills = 0; |
277 } else { | 281 } else { |
278 CollectedHeap::fill_with_object(obj, word_sz); | 282 CollectedHeap::fill_with_object(obj, word_sz); |
279 } | 283 } |
280 } | 284 } |
281 | 285 |
282 void ParScanThreadState::print_and_clear_promotion_failure_size() { | 286 void ParScanThreadState::print_promotion_failure_size() { |
283 if (_promotion_failure_size != 0) { | 287 if (_promotion_failed_info.has_failed() && PrintPromotionFailure) { |
284 if (PrintPromotionFailure) { | 288 gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ", |
285 gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ", | 289 _thread_num, _promotion_failed_info.first_size()); |
286 _thread_num, _promotion_failure_size); | |
287 } | |
288 _promotion_failure_size = 0; | |
289 } | 290 } |
290 } | 291 } |
291 | 292 |
292 class ParScanThreadStateSet: private ResourceArray { | 293 class ParScanThreadStateSet: private ResourceArray { |
293 public: | 294 public: |
303 | 304 |
304 ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); } | 305 ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); } |
305 | 306 |
306 inline ParScanThreadState& thread_state(int i); | 307 inline ParScanThreadState& thread_state(int i); |
307 | 308 |
309 void trace_promotion_failed(YoungGCTracer& gc_tracer); | |
308 void reset(int active_workers, bool promotion_failed); | 310 void reset(int active_workers, bool promotion_failed); |
309 void flush(); | 311 void flush(); |
310 | 312 |
311 #if TASKQUEUE_STATS | 313 #if TASKQUEUE_STATS |
312 static void | 314 static void |
351 { | 353 { |
352 assert(i >= 0 && i < length(), "sanity check!"); | 354 assert(i >= 0 && i < length(), "sanity check!"); |
353 return ((ParScanThreadState*)_data)[i]; | 355 return ((ParScanThreadState*)_data)[i]; |
354 } | 356 } |
355 | 357 |
358 void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) { | |
359 for (int i = 0; i < length(); ++i) { | |
360 if (thread_state(i).promotion_failed()) { | |
361 gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info()); | |
362 thread_state(i).promotion_failed_info().reset(); | |
363 } | |
364 } | |
365 } | |
356 | 366 |
357 void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed) | 367 void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed) |
358 { | 368 { |
359 _term.reset_for_reuse(active_threads); | 369 _term.reset_for_reuse(active_threads); |
360 if (promotion_failed) { | 370 if (promotion_failed) { |
361 for (int i = 0; i < length(); ++i) { | 371 for (int i = 0; i < length(); ++i) { |
362 thread_state(i).print_and_clear_promotion_failure_size(); | 372 thread_state(i).print_promotion_failure_size(); |
363 } | 373 } |
364 } | 374 } |
365 } | 375 } |
366 | 376 |
367 #if TASKQUEUE_STATS | 377 #if TASKQUEUE_STATS |
580 // Should the heap be passed in? There's only 1 for now so | 590 // Should the heap be passed in? There's only 1 for now so |
581 // grab it instead. | 591 // grab it instead. |
582 GenCollectedHeap* gch = GenCollectedHeap::heap(); | 592 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
583 gch->set_n_termination(active_workers); | 593 gch->set_n_termination(active_workers); |
584 } | 594 } |
585 | |
586 // The "i" passed to this method is the part of the work for | |
587 // this thread. It is not the worker ID. The "i" is derived | |
588 // from _started_workers which is incremented in internal_note_start() | |
589 // called in GangWorker loop() and which is called under the | |
590 // which is called under the protection of the gang monitor and is | |
591 // called after a task is started. So "i" is based on | |
592 // first-come-first-served. | |
593 | 595 |
594 void ParNewGenTask::work(uint worker_id) { | 596 void ParNewGenTask::work(uint worker_id) { |
595 GenCollectedHeap* gch = GenCollectedHeap::heap(); | 597 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
596 // Since this is being done in a separate thread, need new resource | 598 // Since this is being done in a separate thread, need new resource |
597 // and handle marks. | 599 // and handle marks. |
874 _scan_older); | 876 _scan_older); |
875 } while (!_gch->no_allocs_since_save_marks(_level)); | 877 } while (!_gch->no_allocs_since_save_marks(_level)); |
876 } | 878 } |
877 | 879 |
878 | 880 |
881 // A Generation that does parallel young-gen collection. | |
882 | |
879 bool ParNewGeneration::_avoid_promotion_undo = false; | 883 bool ParNewGeneration::_avoid_promotion_undo = false; |
880 | 884 |
881 // A Generation that does parallel young-gen collection. | 885 void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) { |
886 assert(_promo_failure_scan_stack.is_empty(), "post condition"); | |
887 _promo_failure_scan_stack.clear(true); // Clear cached segments. | |
888 | |
889 remove_forwarding_pointers(); | |
890 if (PrintGCDetails) { | |
891 gclog_or_tty->print(" (promotion failed)"); | |
892 } | |
893 // All the spaces are in play for mark-sweep. | |
894 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. | |
895 from()->set_next_compaction_space(to()); | |
896 gch->set_incremental_collection_failed(); | |
897 // Inform the next generation that a promotion failure occurred. | |
898 _next_gen->promotion_failure_occurred(); | |
899 | |
900 // Trace promotion failure in the parallel GC threads | |
901 thread_state_set.trace_promotion_failed(gc_tracer); | |
902 // Single threaded code may have reported promotion failure to the global state | |
903 if (_promotion_failed_info.has_failed()) { | |
904 gc_tracer.report_promotion_failed(_promotion_failed_info); | |
905 } | |
906 // Reset the PromotionFailureALot counters. | |
907 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) | |
908 } | |
882 | 909 |
883 void ParNewGeneration::collect(bool full, | 910 void ParNewGeneration::collect(bool full, |
884 bool clear_all_soft_refs, | 911 bool clear_all_soft_refs, |
885 size_t size, | 912 size_t size, |
886 bool is_tlab) { | 913 bool is_tlab) { |
887 assert(full || size > 0, "otherwise we don't want to collect"); | 914 assert(full || size > 0, "otherwise we don't want to collect"); |
915 | |
888 GenCollectedHeap* gch = GenCollectedHeap::heap(); | 916 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
917 | |
918 _gc_timer->register_gc_start(os::elapsed_counter()); | |
919 | |
889 assert(gch->kind() == CollectedHeap::GenCollectedHeap, | 920 assert(gch->kind() == CollectedHeap::GenCollectedHeap, |
890 "not a CMS generational heap"); | 921 "not a CMS generational heap"); |
891 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy(); | 922 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy(); |
892 FlexibleWorkGang* workers = gch->workers(); | 923 FlexibleWorkGang* workers = gch->workers(); |
893 assert(workers != NULL, "Need workgang for parallel work"); | 924 assert(workers != NULL, "Need workgang for parallel work"); |
904 // Do we have to avoid promotion_undo? | 935 // Do we have to avoid promotion_undo? |
905 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { | 936 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { |
906 set_avoid_promotion_undo(true); | 937 set_avoid_promotion_undo(true); |
907 } | 938 } |
908 | 939 |
909 // If the next generation is too full to accomodate worst-case promotion | 940 // If the next generation is too full to accommodate worst-case promotion |
910 // from this generation, pass on collection; let the next generation | 941 // from this generation, pass on collection; let the next generation |
911 // do it. | 942 // do it. |
912 if (!collection_attempt_is_safe()) { | 943 if (!collection_attempt_is_safe()) { |
913 gch->set_incremental_collection_failed(); // slight lie, in that we did not even attempt one | 944 gch->set_incremental_collection_failed(); // slight lie, in that we did not even attempt one |
914 return; | 945 return; |
915 } | 946 } |
916 assert(to()->is_empty(), "Else not collection_attempt_is_safe"); | 947 assert(to()->is_empty(), "Else not collection_attempt_is_safe"); |
917 | 948 |
949 ParNewTracer gc_tracer; | |
950 gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); | |
951 gch->trace_heap_before_gc(&gc_tracer); | |
952 | |
918 init_assuming_no_promotion_failure(); | 953 init_assuming_no_promotion_failure(); |
919 | 954 |
920 if (UseAdaptiveSizePolicy) { | 955 if (UseAdaptiveSizePolicy) { |
921 set_survivor_overflow(false); | 956 set_survivor_overflow(false); |
922 size_policy->minor_collection_begin(); | 957 size_policy->minor_collection_begin(); |
923 } | 958 } |
924 | 959 |
925 TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty); | 960 GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL); |
926 // Capture heap used before collection (for printing). | 961 // Capture heap used before collection (for printing). |
927 size_t gch_prev_used = gch->used(); | 962 size_t gch_prev_used = gch->used(); |
928 | 963 |
929 SpecializationStats::clear(); | 964 SpecializationStats::clear(); |
930 | 965 |
973 EvacuateFollowersClosureGeneral evacuate_followers(gch, _level, | 1008 EvacuateFollowersClosureGeneral evacuate_followers(gch, _level, |
974 &scan_without_gc_barrier, &scan_with_gc_barrier); | 1009 &scan_without_gc_barrier, &scan_with_gc_barrier); |
975 rp->setup_policy(clear_all_soft_refs); | 1010 rp->setup_policy(clear_all_soft_refs); |
976 // Can the mt_degree be set later (at run_task() time would be best)? | 1011 // Can the mt_degree be set later (at run_task() time would be best)? |
977 rp->set_active_mt_degree(active_workers); | 1012 rp->set_active_mt_degree(active_workers); |
1013 ReferenceProcessorStats stats; | |
978 if (rp->processing_is_mt()) { | 1014 if (rp->processing_is_mt()) { |
979 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); | 1015 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); |
980 rp->process_discovered_references(&is_alive, &keep_alive, | 1016 stats = rp->process_discovered_references(&is_alive, &keep_alive, |
981 &evacuate_followers, &task_executor); | 1017 &evacuate_followers, &task_executor, |
1018 _gc_timer); | |
982 } else { | 1019 } else { |
983 thread_state_set.flush(); | 1020 thread_state_set.flush(); |
984 gch->set_par_threads(0); // 0 ==> non-parallel. | 1021 gch->set_par_threads(0); // 0 ==> non-parallel. |
985 gch->save_marks(); | 1022 gch->save_marks(); |
986 rp->process_discovered_references(&is_alive, &keep_alive, | 1023 stats = rp->process_discovered_references(&is_alive, &keep_alive, |
987 &evacuate_followers, NULL); | 1024 &evacuate_followers, NULL, |
988 } | 1025 _gc_timer); |
1026 } | |
1027 gc_tracer.report_gc_reference_stats(stats); | |
989 if (!promotion_failed()) { | 1028 if (!promotion_failed()) { |
990 // Swap the survivor spaces. | 1029 // Swap the survivor spaces. |
991 eden()->clear(SpaceDecorator::Mangle); | 1030 eden()->clear(SpaceDecorator::Mangle); |
992 from()->clear(SpaceDecorator::Mangle); | 1031 from()->clear(SpaceDecorator::Mangle); |
993 if (ZapUnusedHeapArea) { | 1032 if (ZapUnusedHeapArea) { |
1008 | 1047 |
1009 assert(to()->is_empty(), "to space should be empty now"); | 1048 assert(to()->is_empty(), "to space should be empty now"); |
1010 | 1049 |
1011 adjust_desired_tenuring_threshold(); | 1050 adjust_desired_tenuring_threshold(); |
1012 } else { | 1051 } else { |
1013 assert(_promo_failure_scan_stack.is_empty(), "post condition"); | 1052 handle_promotion_failed(gch, thread_state_set, gc_tracer); |
1014 _promo_failure_scan_stack.clear(true); // Clear cached segments. | |
1015 | |
1016 remove_forwarding_pointers(); | |
1017 if (PrintGCDetails) { | |
1018 gclog_or_tty->print(" (promotion failed)"); | |
1019 } | |
1020 // All the spaces are in play for mark-sweep. | |
1021 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. | |
1022 from()->set_next_compaction_space(to()); | |
1023 gch->set_incremental_collection_failed(); | |
1024 // Inform the next generation that a promotion failure occurred. | |
1025 _next_gen->promotion_failure_occurred(); | |
1026 | |
1027 // Reset the PromotionFailureALot counters. | |
1028 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) | |
1029 } | 1053 } |
1030 // set new iteration safe limit for the survivor spaces | 1054 // set new iteration safe limit for the survivor spaces |
1031 from()->set_concurrent_iteration_safe_limit(from()->top()); | 1055 from()->set_concurrent_iteration_safe_limit(from()->top()); |
1032 to()->set_concurrent_iteration_safe_limit(to()->top()); | 1056 to()->set_concurrent_iteration_safe_limit(to()->top()); |
1033 | 1057 |
1063 rp->enqueue_discovered_references(&task_executor); | 1087 rp->enqueue_discovered_references(&task_executor); |
1064 } else { | 1088 } else { |
1065 rp->enqueue_discovered_references(NULL); | 1089 rp->enqueue_discovered_references(NULL); |
1066 } | 1090 } |
1067 rp->verify_no_references_recorded(); | 1091 rp->verify_no_references_recorded(); |
1092 | |
1093 gch->trace_heap_after_gc(&gc_tracer); | |
1094 gc_tracer.report_tenuring_threshold(tenuring_threshold()); | |
1095 | |
1096 _gc_timer->register_gc_end(os::elapsed_counter()); | |
1097 | |
1098 gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); | |
1068 } | 1099 } |
1069 | 1100 |
1070 static int sum; | 1101 static int sum; |
1071 void ParNewGeneration::waste_some_time() { | 1102 void ParNewGeneration::waste_some_time() { |
1072 for (int i = 0; i < 100; i++) { | 1103 for (int i = 0; i < 100; i++) { |
1172 // promotion failed, forward to self | 1203 // promotion failed, forward to self |
1173 _promotion_failed = true; | 1204 _promotion_failed = true; |
1174 new_obj = old; | 1205 new_obj = old; |
1175 | 1206 |
1176 preserve_mark_if_necessary(old, m); | 1207 preserve_mark_if_necessary(old, m); |
1177 // Log the size of the maiden promotion failure | 1208 par_scan_state->register_promotion_failure(sz); |
1178 par_scan_state->log_promotion_failure(sz); | |
1179 } | 1209 } |
1180 | 1210 |
1181 old->forward_to(new_obj); | 1211 old->forward_to(new_obj); |
1182 forward_ptr = NULL; | 1212 forward_ptr = NULL; |
1183 } else { | 1213 } else { |
1298 | 1328 |
1299 _promotion_failed = true; | 1329 _promotion_failed = true; |
1300 failed_to_promote = true; | 1330 failed_to_promote = true; |
1301 | 1331 |
1302 preserve_mark_if_necessary(old, m); | 1332 preserve_mark_if_necessary(old, m); |
1303 // Log the size of the maiden promotion failure | 1333 par_scan_state->register_promotion_failure(sz); |
1304 par_scan_state->log_promotion_failure(sz); | |
1305 } | 1334 } |
1306 } else { | 1335 } else { |
1307 // Is in to-space; do copying ourselves. | 1336 // Is in to-space; do copying ourselves. |
1308 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz); | 1337 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz); |
1309 // Restore the mark word copied above. | 1338 // Restore the mark word copied above. |
1597 #endif | 1626 #endif |
1598 return true; | 1627 return true; |
1599 } | 1628 } |
1600 #undef BUSY | 1629 #undef BUSY |
1601 | 1630 |
1602 void ParNewGeneration::ref_processor_init() | 1631 void ParNewGeneration::ref_processor_init() { |
1603 { | |
1604 if (_ref_processor == NULL) { | 1632 if (_ref_processor == NULL) { |
1605 // Allocate and initialize a reference processor | 1633 // Allocate and initialize a reference processor |
1606 _ref_processor = | 1634 _ref_processor = |
1607 new ReferenceProcessor(_reserved, // span | 1635 new ReferenceProcessor(_reserved, // span |
1608 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing | 1636 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing |