3064 |
3064 |
3065 bool do_bit(size_t offset) { |
3065 bool do_bit(size_t offset) { |
3066 HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset); |
3066 HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset); |
3067 assert(_nextMarkBitMap->isMarked(addr), "invariant"); |
3067 assert(_nextMarkBitMap->isMarked(addr), "invariant"); |
3068 assert( addr < _cm->finger(), "invariant"); |
3068 assert( addr < _cm->finger(), "invariant"); |
3069 |
|
3070 statsOnly( _task->increase_objs_found_on_bitmap() ); |
|
3071 assert(addr >= _task->finger(), "invariant"); |
3069 assert(addr >= _task->finger(), "invariant"); |
3072 |
3070 |
3073 // We move that task's local finger along. |
3071 // We move that task's local finger along. |
3074 _task->move_finger_to(addr); |
3072 _task->move_finger_to(addr); |
3075 |
3073 |
3191 |
3189 |
3192 _calls = 0; |
3190 _calls = 0; |
3193 _elapsed_time_ms = 0.0; |
3191 _elapsed_time_ms = 0.0; |
3194 _termination_time_ms = 0.0; |
3192 _termination_time_ms = 0.0; |
3195 _termination_start_time_ms = 0.0; |
3193 _termination_start_time_ms = 0.0; |
3196 |
|
3197 #if _MARKING_STATS_ |
|
3198 _aborted = 0; |
|
3199 _aborted_overflow = 0; |
|
3200 _aborted_cm_aborted = 0; |
|
3201 _aborted_yield = 0; |
|
3202 _aborted_timed_out = 0; |
|
3203 _aborted_satb = 0; |
|
3204 _aborted_termination = 0; |
|
3205 _steal_attempts = 0; |
|
3206 _steals = 0; |
|
3207 _local_pushes = 0; |
|
3208 _local_pops = 0; |
|
3209 _local_max_size = 0; |
|
3210 _objs_scanned = 0; |
|
3211 _global_pushes = 0; |
|
3212 _global_pops = 0; |
|
3213 _global_max_size = 0; |
|
3214 _global_transfers_to = 0; |
|
3215 _global_transfers_from = 0; |
|
3216 _regions_claimed = 0; |
|
3217 _objs_found_on_bitmap = 0; |
|
3218 _satb_buffers_processed = 0; |
|
3219 #endif // _MARKING_STATS_ |
|
3220 } |
3194 } |
3221 |
3195 |
3222 bool CMTask::should_exit_termination() { |
3196 bool CMTask::should_exit_termination() { |
3223 regular_clock_call(); |
3197 regular_clock_call(); |
3224 // This is called when we are in the termination protocol. We should |
3198 // This is called when we are in the termination protocol. We should |
3255 if (!concurrent()) return; |
3229 if (!concurrent()) return; |
3256 |
3230 |
3257 // (2) If marking has been aborted for Full GC, then we also abort. |
3231 // (2) If marking has been aborted for Full GC, then we also abort. |
3258 if (_cm->has_aborted()) { |
3232 if (_cm->has_aborted()) { |
3259 set_has_aborted(); |
3233 set_has_aborted(); |
3260 statsOnly( ++_aborted_cm_aborted ); |
|
3261 return; |
3234 return; |
3262 } |
3235 } |
3263 |
3236 |
3264 double curr_time_ms = os::elapsedVTime() * 1000.0; |
3237 double curr_time_ms = os::elapsedVTime() * 1000.0; |
3265 |
|
3266 // (3) If marking stats are enabled, then we update the step history. |
|
3267 #if _MARKING_STATS_ |
|
3268 if (_words_scanned >= _words_scanned_limit) { |
|
3269 ++_clock_due_to_scanning; |
|
3270 } |
|
3271 if (_refs_reached >= _refs_reached_limit) { |
|
3272 ++_clock_due_to_marking; |
|
3273 } |
|
3274 |
|
3275 double last_interval_ms = curr_time_ms - _interval_start_time_ms; |
|
3276 _interval_start_time_ms = curr_time_ms; |
|
3277 _all_clock_intervals_ms.add(last_interval_ms); |
|
3278 |
|
3279 if (_cm->verbose_medium()) { |
|
3280 gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, " |
|
3281 "scanned = " SIZE_FORMAT "%s, refs reached = " SIZE_FORMAT "%s", |
|
3282 _worker_id, last_interval_ms, |
|
3283 _words_scanned, |
|
3284 (_words_scanned >= _words_scanned_limit) ? " (*)" : "", |
|
3285 _refs_reached, |
|
3286 (_refs_reached >= _refs_reached_limit) ? " (*)" : ""); |
|
3287 } |
|
3288 #endif // _MARKING_STATS_ |
|
3289 |
3238 |
3290 // (4) We check whether we should yield. If we have to, then we abort. |
3239 // (4) We check whether we should yield. If we have to, then we abort. |
3291 if (SuspendibleThreadSet::should_yield()) { |
3240 if (SuspendibleThreadSet::should_yield()) { |
3292 // We should yield. To do this we abort the task. The caller is |
3241 // We should yield. To do this we abort the task. The caller is |
3293 // responsible for yielding. |
3242 // responsible for yielding. |
3294 set_has_aborted(); |
3243 set_has_aborted(); |
3295 statsOnly( ++_aborted_yield ); |
|
3296 return; |
3244 return; |
3297 } |
3245 } |
3298 |
3246 |
3299 // (5) We check whether we've reached our time quota. If we have, |
3247 // (5) We check whether we've reached our time quota. If we have, |
3300 // then we abort. |
3248 // then we abort. |
3301 double elapsed_time_ms = curr_time_ms - _start_time_ms; |
3249 double elapsed_time_ms = curr_time_ms - _start_time_ms; |
3302 if (elapsed_time_ms > _time_target_ms) { |
3250 if (elapsed_time_ms > _time_target_ms) { |
3303 set_has_aborted(); |
3251 set_has_aborted(); |
3304 _has_timed_out = true; |
3252 _has_timed_out = true; |
3305 statsOnly( ++_aborted_timed_out ); |
|
3306 return; |
3253 return; |
3307 } |
3254 } |
3308 |
3255 |
3309 // (6) Finally, we check whether there are enough completed STAB |
3256 // (6) Finally, we check whether there are enough completed STAB |
3310 // buffers available for processing. If there are, we abort. |
3257 // buffers available for processing. If there are, we abort. |
3396 _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n); |
3335 _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n); |
3397 assert(n <= global_stack_transfer_size, |
3336 assert(n <= global_stack_transfer_size, |
3398 "we should not pop more than the given limit"); |
3337 "we should not pop more than the given limit"); |
3399 if (n > 0) { |
3338 if (n > 0) { |
3400 // yes, we did actually pop at least one entry |
3339 // yes, we did actually pop at least one entry |
3401 |
|
3402 statsOnly( ++_global_transfers_from; _global_pops += n ); |
|
3403 if (_cm->verbose_medium()) { |
3340 if (_cm->verbose_medium()) { |
3404 gclog_or_tty->print_cr("[%u] popped %d entries from the global stack", |
3341 gclog_or_tty->print_cr("[%u] popped %d entries from the global stack", |
3405 _worker_id, n); |
3342 _worker_id, n); |
3406 } |
3343 } |
3407 for (int i = 0; i < n; ++i) { |
3344 for (int i = 0; i < n; ++i) { |
3408 bool success = _task_queue->push(buffer[i]); |
3345 bool success = _task_queue->push(buffer[i]); |
3409 // We only call this when the local queue is empty or under a |
3346 // We only call this when the local queue is empty or under a |
3410 // given target limit. So, we do not expect this push to fail. |
3347 // given target limit. So, we do not expect this push to fail. |
3411 assert(success, "invariant"); |
3348 assert(success, "invariant"); |
3412 } |
3349 } |
3413 |
|
3414 statsOnly( size_t tmp_size = (size_t)_task_queue->size(); |
|
3415 if (tmp_size > _local_max_size) { |
|
3416 _local_max_size = tmp_size; |
|
3417 } |
|
3418 _local_pushes += n ); |
|
3419 } |
3350 } |
3420 |
3351 |
3421 // this operation was quite expensive, so decrease the limits |
3352 // this operation was quite expensive, so decrease the limits |
3422 decrease_limits(); |
3353 decrease_limits(); |
3423 } |
3354 } |
3555 gclog_or_tty->print_cr(" Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms", |
3483 gclog_or_tty->print_cr(" Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms", |
3556 _step_times_ms.num(), _step_times_ms.avg(), |
3484 _step_times_ms.num(), _step_times_ms.avg(), |
3557 _step_times_ms.sd()); |
3485 _step_times_ms.sd()); |
3558 gclog_or_tty->print_cr(" max = %1.2lfms, total = %1.2lfms", |
3486 gclog_or_tty->print_cr(" max = %1.2lfms, total = %1.2lfms", |
3559 _step_times_ms.maximum(), _step_times_ms.sum()); |
3487 _step_times_ms.maximum(), _step_times_ms.sum()); |
3560 |
|
3561 #if _MARKING_STATS_ |
|
3562 gclog_or_tty->print_cr(" Clock Intervals (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms", |
|
3563 _all_clock_intervals_ms.num(), _all_clock_intervals_ms.avg(), |
|
3564 _all_clock_intervals_ms.sd()); |
|
3565 gclog_or_tty->print_cr(" max = %1.2lfms, total = %1.2lfms", |
|
3566 _all_clock_intervals_ms.maximum(), |
|
3567 _all_clock_intervals_ms.sum()); |
|
3568 gclog_or_tty->print_cr(" Clock Causes (cum): scanning = " SIZE_FORMAT ", marking = " SIZE_FORMAT, |
|
3569 _clock_due_to_scanning, _clock_due_to_marking); |
|
3570 gclog_or_tty->print_cr(" Objects: scanned = " SIZE_FORMAT ", found on the bitmap = " SIZE_FORMAT, |
|
3571 _objs_scanned, _objs_found_on_bitmap); |
|
3572 gclog_or_tty->print_cr(" Local Queue: pushes = " SIZE_FORMAT ", pops = " SIZE_FORMAT ", max size = " SIZE_FORMAT, |
|
3573 _local_pushes, _local_pops, _local_max_size); |
|
3574 gclog_or_tty->print_cr(" Global Stack: pushes = " SIZE_FORMAT ", pops = " SIZE_FORMAT ", max size = " SIZE_FORMAT, |
|
3575 _global_pushes, _global_pops, _global_max_size); |
|
3576 gclog_or_tty->print_cr(" transfers to = " SIZE_FORMAT ", transfers from = " SIZE_FORMAT, |
|
3577 _global_transfers_to,_global_transfers_from); |
|
3578 gclog_or_tty->print_cr(" Regions: claimed = " SIZE_FORMAT, _regions_claimed); |
|
3579 gclog_or_tty->print_cr(" SATB buffers: processed = " SIZE_FORMAT, _satb_buffers_processed); |
|
3580 gclog_or_tty->print_cr(" Steals: attempts = " SIZE_FORMAT ", successes = " SIZE_FORMAT, |
|
3581 _steal_attempts, _steals); |
|
3582 gclog_or_tty->print_cr(" Aborted: " SIZE_FORMAT ", due to", _aborted); |
|
3583 gclog_or_tty->print_cr(" overflow: " SIZE_FORMAT ", global abort: " SIZE_FORMAT ", yield: " SIZE_FORMAT, |
|
3584 _aborted_overflow, _aborted_cm_aborted, _aborted_yield); |
|
3585 gclog_or_tty->print_cr(" time out: " SIZE_FORMAT ", SATB: " SIZE_FORMAT ", termination: " SIZE_FORMAT, |
|
3586 _aborted_timed_out, _aborted_satb, _aborted_termination); |
|
3587 #endif // _MARKING_STATS_ |
|
3588 } |
3488 } |
3589 |
3489 |
3590 bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) { |
3490 bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) { |
3591 return _task_queues->steal(worker_id, hash_seed, obj); |
3491 return _task_queues->steal(worker_id, hash_seed, obj); |
3592 } |
3492 } |
3725 // time. But it is only for debugging purposes anyway and it will |
3625 // time. But it is only for debugging purposes anyway and it will |
3726 // catch most problems. |
3626 // catch most problems. |
3727 _claimed = true; |
3627 _claimed = true; |
3728 |
3628 |
3729 _start_time_ms = os::elapsedVTime() * 1000.0; |
3629 _start_time_ms = os::elapsedVTime() * 1000.0; |
3730 statsOnly( _interval_start_time_ms = _start_time_ms ); |
|
3731 |
3630 |
3732 // If do_stealing is true then do_marking_step will attempt to |
3631 // If do_stealing is true then do_marking_step will attempt to |
3733 // steal work from the other CMTasks. It only makes sense to |
3632 // steal work from the other CMTasks. It only makes sense to |
3734 // enable stealing when the termination protocol is enabled |
3633 // enable stealing when the termination protocol is enabled |
3735 // and do_marking_step() is not being called serially. |
3634 // and do_marking_step() is not being called serially. |
3885 gclog_or_tty->print_cr("[%u] trying to claim a new region", _worker_id); |
3784 gclog_or_tty->print_cr("[%u] trying to claim a new region", _worker_id); |
3886 } |
3785 } |
3887 HeapRegion* claimed_region = _cm->claim_region(_worker_id); |
3786 HeapRegion* claimed_region = _cm->claim_region(_worker_id); |
3888 if (claimed_region != NULL) { |
3787 if (claimed_region != NULL) { |
3889 // Yes, we managed to claim one |
3788 // Yes, we managed to claim one |
3890 statsOnly( ++_regions_claimed ); |
|
3891 |
|
3892 if (_cm->verbose_low()) { |
3789 if (_cm->verbose_low()) { |
3893 gclog_or_tty->print_cr("[%u] we successfully claimed " |
3790 gclog_or_tty->print_cr("[%u] we successfully claimed " |
3894 "region " PTR_FORMAT, |
3791 "region " PTR_FORMAT, |
3895 _worker_id, p2i(claimed_region)); |
3792 _worker_id, p2i(claimed_region)); |
3896 } |
3793 } |
3946 gclog_or_tty->print_cr("[%u] starting to steal", _worker_id); |
3843 gclog_or_tty->print_cr("[%u] starting to steal", _worker_id); |
3947 } |
3844 } |
3948 |
3845 |
3949 while (!has_aborted()) { |
3846 while (!has_aborted()) { |
3950 oop obj; |
3847 oop obj; |
3951 statsOnly( ++_steal_attempts ); |
|
3952 |
|
3953 if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) { |
3848 if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) { |
3954 if (_cm->verbose_medium()) { |
3849 if (_cm->verbose_medium()) { |
3955 gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully", |
3850 gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully", |
3956 _worker_id, p2i((void*) obj)); |
3851 _worker_id, p2i((void*) obj)); |
3957 } |
3852 } |
3958 |
|
3959 statsOnly( ++_steals ); |
|
3960 |
3853 |
3961 assert(_nextMarkBitMap->isMarked((HeapWord*) obj), |
3854 assert(_nextMarkBitMap->isMarked((HeapWord*) obj), |
3962 "any stolen object should be marked"); |
3855 "any stolen object should be marked"); |
3963 scan_object(obj); |
3856 scan_object(obj); |
3964 |
3857 |
4055 // Update the step history. |
3947 // Update the step history. |
4056 _step_times_ms.add(elapsed_time_ms); |
3948 _step_times_ms.add(elapsed_time_ms); |
4057 |
3949 |
4058 if (has_aborted()) { |
3950 if (has_aborted()) { |
4059 // The task was aborted for some reason. |
3951 // The task was aborted for some reason. |
4060 |
|
4061 statsOnly( ++_aborted ); |
|
4062 |
|
4063 if (_has_timed_out) { |
3952 if (_has_timed_out) { |
4064 double diff_ms = elapsed_time_ms - _time_target_ms; |
3953 double diff_ms = elapsed_time_ms - _time_target_ms; |
4065 // Keep statistics of how well we did with respect to hitting |
3954 // Keep statistics of how well we did with respect to hitting |
4066 // our target only if we actually timed out (if we aborted for |
3955 // our target only if we actually timed out (if we aborted for |
4067 // other reasons, then the results might get skewed). |
3956 // other reasons, then the results might get skewed). |
4140 _cm_oop_closure(NULL), |
4027 _cm_oop_closure(NULL), |
4141 _marked_bytes_array(marked_bytes), |
4028 _marked_bytes_array(marked_bytes), |
4142 _card_bm(card_bm) { |
4029 _card_bm(card_bm) { |
4143 guarantee(task_queue != NULL, "invariant"); |
4030 guarantee(task_queue != NULL, "invariant"); |
4144 guarantee(task_queues != NULL, "invariant"); |
4031 guarantee(task_queues != NULL, "invariant"); |
4145 |
|
4146 statsOnly( _clock_due_to_scanning = 0; |
|
4147 _clock_due_to_marking = 0 ); |
|
4148 |
4032 |
4149 _marking_step_diffs_ms.add(0.5); |
4033 _marking_step_diffs_ms.add(0.5); |
4150 } |
4034 } |
4151 |
4035 |
4152 // These are formatting macros that are used below to ensure |
4036 // These are formatting macros that are used below to ensure |