Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/concurrentMark.cpp @ 8788:e864cc14ca75
8009940: G1: assert(_finger == _heap_end) failed, concurrentMark.cpp:809
Summary: Skip reference processing if the global marking stack overflows during remark. Refactor and rename set_phase(); move code that sets the concurrency level into its own routine. Do not call set_phase() from within parallel reference processing; use the concurrency level routine instead. The marking state should only set reset by CMTask[0] during the concurrent phase of the marking cycle; if an overflow occurs at any stage during the remark, the marking state will be reset after reference processing.
Reviewed-by: brutisso, jmasa
author | johnc |
---|---|
date | Tue, 19 Mar 2013 00:57:39 -0700 |
parents | fa08949fe0cb |
children | 1179172e9ec9 |
comparison
equal
deleted
inserted
replaced
8787:fa08949fe0cb | 8788:e864cc14ca75 |
---|---|
782 CMTaskQueue* queue = _task_queues->queue(i); | 782 CMTaskQueue* queue = _task_queues->queue(i); |
783 queue->set_empty(); | 783 queue->set_empty(); |
784 } | 784 } |
785 } | 785 } |
786 | 786 |
787 void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { | 787 void ConcurrentMark::set_concurrency(uint active_tasks) { |
788 assert(active_tasks <= _max_worker_id, "we should not have more"); | 788 assert(active_tasks <= _max_worker_id, "we should not have more"); |
789 | 789 |
790 _active_tasks = active_tasks; | 790 _active_tasks = active_tasks; |
791 // Need to update the three data structures below according to the | 791 // Need to update the three data structures below according to the |
792 // number of active threads for this phase. | 792 // number of active threads for this phase. |
793 _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues); | 793 _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues); |
794 _first_overflow_barrier_sync.set_n_workers((int) active_tasks); | 794 _first_overflow_barrier_sync.set_n_workers((int) active_tasks); |
795 _second_overflow_barrier_sync.set_n_workers((int) active_tasks); | 795 _second_overflow_barrier_sync.set_n_workers((int) active_tasks); |
796 } | |
797 | |
798 void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurrent) { | |
799 set_concurrency(active_tasks); | |
796 | 800 |
797 _concurrent = concurrent; | 801 _concurrent = concurrent; |
798 // We propagate this to all tasks, not just the active ones. | 802 // We propagate this to all tasks, not just the active ones. |
799 for (uint i = 0; i < _max_worker_id; ++i) | 803 for (uint i = 0; i < _max_worker_id; ++i) |
800 _tasks[i]->set_concurrent(concurrent); | 804 _tasks[i]->set_concurrent(concurrent); |
804 } else { | 808 } else { |
805 // We currently assume that the concurrent flag has been set to | 809 // We currently assume that the concurrent flag has been set to |
806 // false before we start remark. At this point we should also be | 810 // false before we start remark. At this point we should also be |
807 // in a STW phase. | 811 // in a STW phase. |
808 assert(!concurrent_marking_in_progress(), "invariant"); | 812 assert(!concurrent_marking_in_progress(), "invariant"); |
809 assert(_finger == _heap_end, "only way to get here"); | 813 assert(_finger == _heap_end, |
814 err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, | |
815 _finger, _heap_end)); | |
810 update_g1_committed(true); | 816 update_g1_committed(true); |
811 } | 817 } |
812 } | 818 } |
813 | 819 |
814 void ConcurrentMark::set_non_marking_state() { | 820 void ConcurrentMark::set_non_marking_state() { |
972 | 978 |
973 if (verbose_low()) { | 979 if (verbose_low()) { |
974 gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); | 980 gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); |
975 } | 981 } |
976 | 982 |
977 // let the task associated with with worker 0 do this | 983 // If we're executing the concurrent phase of marking, reset the marking |
978 if (worker_id == 0) { | 984 // state; otherwise the marking state is reset after reference processing, |
979 // task 0 is responsible for clearing the global data structures | 985 // during the remark pause. |
980 // We should be here because of an overflow. During STW we should | 986 // If we reset here as a result of an overflow during the remark we will |
981 // not clear the overflow flag since we rely on it being true when | 987 // see assertion failures from any subsequent set_concurrency_and_phase() |
982 // we exit this method to abort the pause and restart concurent | 988 // calls. |
983 // marking. | 989 if (concurrent()) { |
984 reset_marking_state(concurrent() /* clear_overflow */); | 990 // let the task associated with with worker 0 do this |
985 force_overflow()->update(); | 991 if (worker_id == 0) { |
986 | 992 // task 0 is responsible for clearing the global data structures |
987 if (G1Log::fine()) { | 993 // We should be here because of an overflow. During STW we should |
988 gclog_or_tty->date_stamp(PrintGCDateStamps); | 994 // not clear the overflow flag since we rely on it being true when |
989 gclog_or_tty->stamp(PrintGCTimeStamps); | 995 // we exit this method to abort the pause and restart concurent |
990 gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); | 996 // marking. |
997 reset_marking_state(true /* clear_overflow */); | |
998 force_overflow()->update(); | |
999 | |
1000 if (G1Log::fine()) { | |
1001 gclog_or_tty->date_stamp(PrintGCDateStamps); | |
1002 gclog_or_tty->stamp(PrintGCTimeStamps); | |
1003 gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); | |
1004 } | |
991 } | 1005 } |
992 } | 1006 } |
993 | 1007 |
994 // after this, each task should reset its own data structures then | 1008 // after this, each task should reset its own data structures then |
995 // then go into the second barrier | 1009 // then go into the second barrier |
1005 } | 1019 } |
1006 _second_overflow_barrier_sync.enter(); | 1020 _second_overflow_barrier_sync.enter(); |
1007 if (concurrent()) { | 1021 if (concurrent()) { |
1008 ConcurrentGCThread::stsJoin(); | 1022 ConcurrentGCThread::stsJoin(); |
1009 } | 1023 } |
1010 // at this point everything should be re-initialised and ready to go | 1024 // at this point everything should be re-initialized and ready to go |
1011 | 1025 |
1012 if (verbose_low()) { | 1026 if (verbose_low()) { |
1013 gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); | 1027 gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); |
1014 } | 1028 } |
1015 } | 1029 } |
1220 assert(parallel_marking_threads() <= max_parallel_marking_threads(), | 1234 assert(parallel_marking_threads() <= max_parallel_marking_threads(), |
1221 "Maximum number of marking threads exceeded"); | 1235 "Maximum number of marking threads exceeded"); |
1222 | 1236 |
1223 uint active_workers = MAX2(1U, parallel_marking_threads()); | 1237 uint active_workers = MAX2(1U, parallel_marking_threads()); |
1224 | 1238 |
1225 // Parallel task terminator is set in "set_phase()" | 1239 // Parallel task terminator is set in "set_concurrency_and_phase()" |
1226 set_phase(active_workers, true /* concurrent */); | 1240 set_concurrency_and_phase(active_workers, true /* concurrent */); |
1227 | 1241 |
1228 CMConcurrentMarkingTask markingTask(this, cmThread()); | 1242 CMConcurrentMarkingTask markingTask(this, cmThread()); |
1229 if (use_parallel_marking_threads()) { | 1243 if (use_parallel_marking_threads()) { |
1230 _parallel_workers->set_active_workers((int)active_workers); | 1244 _parallel_workers->set_active_workers((int)active_workers); |
1231 // Don't set _n_par_threads because it affects MT in proceess_strong_roots() | 1245 // Don't set _n_par_threads because it affects MT in proceess_strong_roots() |
2347 assert(_workers != NULL, "Need parallel worker threads."); | 2361 assert(_workers != NULL, "Need parallel worker threads."); |
2348 assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); | 2362 assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); |
2349 | 2363 |
2350 G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm); | 2364 G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm); |
2351 | 2365 |
2352 // We need to reset the phase for each task execution so that | 2366 // We need to reset the concurrency level before each |
2353 // the termination protocol of CMTask::do_marking_step works. | 2367 // proxy task execution, so that the termination protocol |
2354 _cm->set_phase(_active_workers, false /* concurrent */); | 2368 // and overflow handling in CMTask::do_marking_step() knows |
2369 // how many workers to wait for. | |
2370 _cm->set_concurrency(_active_workers); | |
2355 _g1h->set_par_threads(_active_workers); | 2371 _g1h->set_par_threads(_active_workers); |
2356 _workers->run_task(&proc_task_proxy); | 2372 _workers->run_task(&proc_task_proxy); |
2357 _g1h->set_par_threads(0); | 2373 _g1h->set_par_threads(0); |
2358 } | 2374 } |
2359 | 2375 |
2375 assert(_workers != NULL, "Need parallel worker threads."); | 2391 assert(_workers != NULL, "Need parallel worker threads."); |
2376 assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); | 2392 assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); |
2377 | 2393 |
2378 G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); | 2394 G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); |
2379 | 2395 |
2396 // Not strictly necessary but... | |
2397 // | |
2398 // We need to reset the concurrency level before each | |
2399 // proxy task execution, so that the termination protocol | |
2400 // and overflow handling in CMTask::do_marking_step() knows | |
2401 // how many workers to wait for. | |
2402 _cm->set_concurrency(_active_workers); | |
2380 _g1h->set_par_threads(_active_workers); | 2403 _g1h->set_par_threads(_active_workers); |
2381 _workers->run_task(&enq_task_proxy); | 2404 _workers->run_task(&enq_task_proxy); |
2382 _g1h->set_par_threads(0); | 2405 _g1h->set_par_threads(0); |
2383 } | 2406 } |
2384 | 2407 |
2385 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { | 2408 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { |
2409 if (has_overflown()) { | |
2410 // Skip processing the discovered references if we have | |
2411 // overflown the global marking stack. Reference objects | |
2412 // only get discovered once so it is OK to not | |
2413 // de-populate the discovered reference lists. We could have, | |
2414 // but the only benefit would be that, when marking restarts, | |
2415 // less reference objects are discovered. | |
2416 return; | |
2417 } | |
2418 | |
2386 ResourceMark rm; | 2419 ResourceMark rm; |
2387 HandleMark hm; | 2420 HandleMark hm; |
2388 | 2421 |
2389 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 2422 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2390 | 2423 |
2435 | 2468 |
2436 // Parallel processing task executor. | 2469 // Parallel processing task executor. |
2437 G1CMRefProcTaskExecutor par_task_executor(g1h, this, | 2470 G1CMRefProcTaskExecutor par_task_executor(g1h, this, |
2438 g1h->workers(), active_workers); | 2471 g1h->workers(), active_workers); |
2439 AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL); | 2472 AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL); |
2473 | |
2474 // Set the concurrency level. The phase was already set prior to | |
2475 // executing the remark task. | |
2476 set_concurrency(active_workers); | |
2440 | 2477 |
2441 // Set the degree of MT processing here. If the discovery was done MT, | 2478 // Set the degree of MT processing here. If the discovery was done MT, |
2442 // the number of threads involved during discovery could differ from | 2479 // the number of threads involved during discovery could differ from |
2443 // the number of active workers. This is OK as long as the discovered | 2480 // the number of active workers. This is OK as long as the discovered |
2444 // Reference lists are balanced (see balance_all_queues() and balance_queues()). | 2481 // Reference lists are balanced (see balance_all_queues() and balance_queues()). |
2525 if (active_workers == 0) { | 2562 if (active_workers == 0) { |
2526 assert(active_workers > 0, "Should have been set earlier"); | 2563 assert(active_workers > 0, "Should have been set earlier"); |
2527 active_workers = (uint) ParallelGCThreads; | 2564 active_workers = (uint) ParallelGCThreads; |
2528 g1h->workers()->set_active_workers(active_workers); | 2565 g1h->workers()->set_active_workers(active_workers); |
2529 } | 2566 } |
2530 set_phase(active_workers, false /* concurrent */); | 2567 set_concurrency_and_phase(active_workers, false /* concurrent */); |
2531 // Leave _parallel_marking_threads at it's | 2568 // Leave _parallel_marking_threads at it's |
2532 // value originally calculated in the ConcurrentMark | 2569 // value originally calculated in the ConcurrentMark |
2533 // constructor and pass values of the active workers | 2570 // constructor and pass values of the active workers |
2534 // through the gang in the task. | 2571 // through the gang in the task. |
2535 | 2572 |
2541 g1h->workers()->run_task(&remarkTask); | 2578 g1h->workers()->run_task(&remarkTask); |
2542 g1h->set_par_threads(0); | 2579 g1h->set_par_threads(0); |
2543 } else { | 2580 } else { |
2544 G1CollectedHeap::StrongRootsScope srs(g1h); | 2581 G1CollectedHeap::StrongRootsScope srs(g1h); |
2545 uint active_workers = 1; | 2582 uint active_workers = 1; |
2546 set_phase(active_workers, false /* concurrent */); | 2583 set_concurrency_and_phase(active_workers, false /* concurrent */); |
2547 | 2584 |
2548 // Note - if there's no work gang then the VMThread will be | 2585 // Note - if there's no work gang then the VMThread will be |
2549 // the thread to execute the remark - serially. We have | 2586 // the thread to execute the remark - serially. We have |
2550 // to pass true for the is_serial parameter so that | 2587 // to pass true for the is_serial parameter so that |
2551 // CMTask::do_marking_step() doesn't enter the sync | 2588 // CMTask::do_marking_step() doesn't enter the sync |
3921 (1) When the marking phase has been aborted (after a Full GC). | 3958 (1) When the marking phase has been aborted (after a Full GC). |
3922 | 3959 |
3923 (2) When a global overflow (on the global stack) has been | 3960 (2) When a global overflow (on the global stack) has been |
3924 triggered. Before the task aborts, it will actually sync up with | 3961 triggered. Before the task aborts, it will actually sync up with |
3925 the other tasks to ensure that all the marking data structures | 3962 the other tasks to ensure that all the marking data structures |
3926 (local queues, stacks, fingers etc.) are re-initialised so that | 3963 (local queues, stacks, fingers etc.) are re-initialized so that |
3927 when do_marking_step() completes, the marking phase can | 3964 when do_marking_step() completes, the marking phase can |
3928 immediately restart. | 3965 immediately restart. |
3929 | 3966 |
3930 (3) When enough completed SATB buffers are available. The | 3967 (3) When enough completed SATB buffers are available. The |
3931 do_marking_step() method only tries to drain SATB buffers right | 3968 do_marking_step() method only tries to drain SATB buffers right |
4369 | 4406 |
4370 if (!is_serial) { | 4407 if (!is_serial) { |
4371 // ...and enter the second barrier. | 4408 // ...and enter the second barrier. |
4372 _cm->enter_second_sync_barrier(_worker_id); | 4409 _cm->enter_second_sync_barrier(_worker_id); |
4373 } | 4410 } |
4374 // At this point everything has bee re-initialised and we're | 4411 // At this point, if we're during the concurrent phase of |
4412 // marking, everything has been re-initialized and we're | |
4375 // ready to restart. | 4413 // ready to restart. |
4376 } | 4414 } |
4377 | 4415 |
4378 if (_cm->verbose_low()) { | 4416 if (_cm->verbose_low()) { |
4379 gclog_or_tty->print_cr("[%u] <<<<<<<<<< ABORTING, target = %1.2lfms, " | 4417 gclog_or_tty->print_cr("[%u] <<<<<<<<<< ABORTING, target = %1.2lfms, " |