1 /*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
248 // Add the size of this object to the number of marked bytes.
249 marked_bytes += obj_size * HeapWordSize;
250
251 // Find the next marked object after this one.
252 start = mark_bitmap->getNextMarkedWordAddress(obj_end, ntams);
253 }
254
255 return marked_bytes;
256 }
257
258 G1CardLiveDataHelper(G1CardLiveData* live_data, HeapWord* base_address) :
259 _region_bm(live_data->live_regions_bm()),
260 _card_bm(live_data->live_cards_bm()) {
261 // Calculate the card number for the bottom of the heap. Used
262 // in biasing indexes into the accounting card bitmaps.
263 _heap_card_bias =
264 uintptr_t(base_address) >> CardTableModRefBS::card_shift;
265 }
266 };
267
268 class G1CreateCardLiveDataTask: public AbstractGangTask {
269 // Aggregate the counting data that was constructed concurrently
270 // with marking.
271 class G1CreateLiveDataClosure : public HeapRegionClosure {
272 G1CardLiveDataHelper _helper;
273
274 G1CMBitMap* _mark_bitmap;
275
276 G1ConcurrentMark* _cm;
277 public:
278 G1CreateLiveDataClosure(G1CollectedHeap* g1h,
279 G1ConcurrentMark* cm,
280 G1CMBitMap* mark_bitmap,
281 G1CardLiveData* live_data) :
282 HeapRegionClosure(),
283 _helper(live_data, g1h->reserved_region().start()),
284 _mark_bitmap(mark_bitmap),
285 _cm(cm) { }
286
287 bool doHeapRegion(HeapRegion* hr) {
288 size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr);
289 if (marked_bytes > 0) {
290 hr->add_to_marked_bytes(marked_bytes);
291 }
292
293 return (_cm->do_yield_check() && _cm->has_aborted());
294 }
295 };
296
297 G1ConcurrentMark* _cm;
298 G1CardLiveData* _live_data;
299 HeapRegionClaimer _hr_claimer;
300
301 public:
302 G1CreateCardLiveDataTask(G1CMBitMap* bitmap,
303 G1CardLiveData* live_data,
304 uint n_workers) :
305 AbstractGangTask("G1 Create Live Data"),
306 _live_data(live_data),
307 _hr_claimer(n_workers) {
308 }
309
310 void work(uint worker_id) {
311 SuspendibleThreadSetJoiner sts_join;
312
313 G1CollectedHeap* g1h = G1CollectedHeap::heap();
314 G1ConcurrentMark* cm = g1h->concurrent_mark();
315 G1CreateLiveDataClosure cl(g1h, cm, cm->nextMarkBitMap(), _live_data);
316 g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
317 }
318 };
319
320 void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
321 _gc_timestamp_at_create = G1CollectedHeap::heap()->get_gc_time_stamp();
322
323 uint n_workers = workers->active_workers();
324
325 G1CreateCardLiveDataTask cl(mark_bitmap,
326 this,
327 n_workers);
328 workers->run_task(&cl);
329 }
330
331 class G1FinalizeCardLiveDataTask: public AbstractGangTask {
332 // Finalizes the liveness counting data.
333 // Sets the bits corresponding to the interval [NTAMS, top]
334 // (which contains the implicitly live objects) in the
335 // card liveness bitmap. Also sets the bit for each region
336 // containing live data, in the region liveness bitmap.
337 class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
338 private:
339 G1CardLiveDataHelper _helper;
340
341 uint _gc_timestamp_at_create;
342
343 bool has_been_reclaimed(HeapRegion* hr) const {
344 return hr->get_gc_time_stamp() > _gc_timestamp_at_create;
345 }
346 public:
347 G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
348 G1CMBitMap* bitmap,
349 G1CardLiveData* live_data) :
350 HeapRegionClosure(),
351 _helper(live_data, g1h->reserved_region().start()),
352 _gc_timestamp_at_create(live_data->gc_timestamp_at_create()) { }
353
354 bool doHeapRegion(HeapRegion* hr) {
355 if (has_been_reclaimed(hr)) {
356 _helper.reset_live_data(hr);
357 }
358 bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
359 if (allocated_since_marking || hr->next_marked_bytes() > 0) {
360 _helper.set_bit_for_region(hr);
361 }
362 return false;
363 }
364 };
365
366 G1CMBitMap* _bitmap;
367
368 G1CardLiveData* _live_data;
369
370 HeapRegionClaimer _hr_claimer;
371
372 public:
373 G1FinalizeCardLiveDataTask(G1CMBitMap* bitmap, G1CardLiveData* live_data, uint n_workers) :
374 AbstractGangTask("G1 Finalize Card Live Data"),
375 _bitmap(bitmap),
376 _live_data(live_data),
377 _hr_claimer(n_workers) {
378 }
379
380 void work(uint worker_id) {
381 G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data);
382
383 G1CollectedHeap::heap()->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
384 }
385 };
386
387 void G1CardLiveData::finalize(WorkGang* workers, G1CMBitMap* mark_bitmap) {
388 // Finalize the live data.
389 G1FinalizeCardLiveDataTask cl(mark_bitmap,
390 this,
391 workers->active_workers());
392 workers->run_task(&cl);
393 }
394
395 class G1ClearCardLiveDataTask : public AbstractGangTask {
396 BitMapView _bitmap;
397 size_t _num_chunks;
398 size_t _cur_chunk;
399 public:
400 G1ClearCardLiveDataTask(const BitMapView& bitmap, size_t num_tasks) :
401 AbstractGangTask("G1 Clear Card Live Data"),
402 _bitmap(bitmap),
403 _num_chunks(num_tasks),
419 }
420 }
421 };
422
423 void G1CardLiveData::clear(WorkGang* workers) {
424 guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
425
426 size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
427 uint const num_workers = (uint)MIN2(num_chunks, (size_t)workers->active_workers());
428
429 G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
430
431 log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks);
432 workers->run_task(&cl, num_workers);
433
434 // The region live bitmap is always very small, even for huge heaps. Clear
435 // directly.
436 live_regions_bm().clear();
437 }
438
439 class G1VerifyCardLiveDataTask: public AbstractGangTask {
440 // Heap region closure used for verifying the live count data
441 // that was created concurrently and finalized during
442 // the remark pause. This closure is applied to the heap
443 // regions during the STW cleanup pause.
444 class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
445 private:
446 G1CollectedHeap* _g1h;
447 G1CMBitMap* _mark_bitmap;
448 G1CardLiveDataHelper _helper;
449
450 G1CardLiveData* _act_live_data;
451
452 G1CardLiveData* _exp_live_data;
453
454 int _failures;
455
456 // Completely recreates the live data count for the given heap region and
457 // returns the number of bytes marked.
458 size_t create_live_data_count(HeapRegion* hr) {
459 size_t bytes_marked = _helper.mark_marked_during_marking(_mark_bitmap, hr);
520 }
521 }
522
523 _failures += failures;
524
525 // We could stop iteration over the heap when we
526 // find the first violating region by returning true.
527 return false;
528 }
529 };
530 protected:
531 G1CollectedHeap* _g1h;
532 G1CMBitMap* _mark_bitmap;
533
534 G1CardLiveData* _act_live_data;
535
536 G1CardLiveData _exp_live_data;
537
538 int _failures;
539
540 HeapRegionClaimer _hr_claimer;
541
542 public:
543 G1VerifyCardLiveDataTask(G1CMBitMap* bitmap,
544 G1CardLiveData* act_live_data,
545 uint n_workers)
546 : AbstractGangTask("G1 Verify Card Live Data"),
547 _g1h(G1CollectedHeap::heap()),
548 _mark_bitmap(bitmap),
549 _act_live_data(act_live_data),
550 _exp_live_data(),
551 _failures(0),
552 _hr_claimer(n_workers) {
553 assert(VerifyDuringGC, "don't call this otherwise");
554 _exp_live_data.initialize(_g1h->max_capacity(), _g1h->max_regions());
555 }
556
557 void work(uint worker_id) {
558 G1VerifyCardLiveDataClosure cl(_g1h,
559 _mark_bitmap,
560 _act_live_data,
561 &_exp_live_data);
562 _g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
563
564 Atomic::add(cl.failures(), &_failures);
565 }
566
567 int failures() const { return _failures; }
568 };
569
570 void G1CardLiveData::verify(WorkGang* workers, G1CMBitMap* actual_bitmap) {
571 ResourceMark rm;
572
573 G1VerifyCardLiveDataTask cl(actual_bitmap,
574 this,
575 workers->active_workers());
576 workers->run_task(&cl);
577
578 guarantee(cl.failures() == 0, "Unexpected accounting failures");
579 }
580
581 #ifndef PRODUCT
582 void G1CardLiveData::verify_is_clear() {
|
1 /*
2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
248 // Add the size of this object to the number of marked bytes.
249 marked_bytes += obj_size * HeapWordSize;
250
251 // Find the next marked object after this one.
252 start = mark_bitmap->getNextMarkedWordAddress(obj_end, ntams);
253 }
254
255 return marked_bytes;
256 }
257
258 G1CardLiveDataHelper(G1CardLiveData* live_data, HeapWord* base_address) :
259 _region_bm(live_data->live_regions_bm()),
260 _card_bm(live_data->live_cards_bm()) {
261 // Calculate the card number for the bottom of the heap. Used
262 // in biasing indexes into the accounting card bitmaps.
263 _heap_card_bias =
264 uintptr_t(base_address) >> CardTableModRefBS::card_shift;
265 }
266 };
267
268 class G1CreateCardLiveDataTask: public G1ParallelizeByRegionsTask {
269 // Aggregate the counting data that was constructed concurrently
270 // with marking.
271 class G1CreateLiveDataClosure : public HeapRegionClosure {
272 G1CardLiveDataHelper _helper;
273
274 G1CMBitMap* _mark_bitmap;
275
276 G1ConcurrentMark* _cm;
277 public:
278 G1CreateLiveDataClosure(G1CollectedHeap* g1h,
279 G1ConcurrentMark* cm,
280 G1CMBitMap* mark_bitmap,
281 G1CardLiveData* live_data) :
282 HeapRegionClosure(),
283 _helper(live_data, g1h->reserved_region().start()),
284 _mark_bitmap(mark_bitmap),
285 _cm(cm) { }
286
287 bool doHeapRegion(HeapRegion* hr) {
288 size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr);
289 if (marked_bytes > 0) {
290 hr->add_to_marked_bytes(marked_bytes);
291 }
292
293 return (_cm->do_yield_check() && _cm->has_aborted());
294 }
295 };
296
297 G1ConcurrentMark* _cm;
298 G1CardLiveData* _live_data;
299
300 public:
301 G1CreateCardLiveDataTask(G1CMBitMap* bitmap,
302 G1CardLiveData* live_data,
303 uint n_workers) :
304 G1ParallelizeByRegionsTask("G1 Create Live Data", n_workers),
305 _live_data(live_data) {
306 }
307
308 void work(uint worker_id) {
309 SuspendibleThreadSetJoiner sts_join;
310
311 G1CollectedHeap* g1h = G1CollectedHeap::heap();
312 G1ConcurrentMark* cm = g1h->concurrent_mark();
313 G1CreateLiveDataClosure cl(g1h, cm, cm->nextMarkBitMap(), _live_data);
314 all_heap_regions_work(&cl, worker_id);
315 }
316 };
317
318 void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
319 _gc_timestamp_at_create = G1CollectedHeap::heap()->get_gc_time_stamp();
320
321 uint n_workers = workers->active_workers();
322
323 G1CreateCardLiveDataTask cl(mark_bitmap,
324 this,
325 n_workers);
326 workers->run_task(&cl);
327 }
328
329 class G1FinalizeCardLiveDataTask: public G1ParallelizeByRegionsTask {
330 // Finalizes the liveness counting data.
331 // Sets the bits corresponding to the interval [NTAMS, top]
332 // (which contains the implicitly live objects) in the
333 // card liveness bitmap. Also sets the bit for each region
334 // containing live data, in the region liveness bitmap.
335 class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
336 private:
337 G1CardLiveDataHelper _helper;
338
339 uint _gc_timestamp_at_create;
340
341 bool has_been_reclaimed(HeapRegion* hr) const {
342 return hr->get_gc_time_stamp() > _gc_timestamp_at_create;
343 }
344 public:
345 G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
346 G1CMBitMap* bitmap,
347 G1CardLiveData* live_data) :
348 HeapRegionClosure(),
349 _helper(live_data, g1h->reserved_region().start()),
350 _gc_timestamp_at_create(live_data->gc_timestamp_at_create()) { }
351
352 bool doHeapRegion(HeapRegion* hr) {
353 if (has_been_reclaimed(hr)) {
354 _helper.reset_live_data(hr);
355 }
356 bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
357 if (allocated_since_marking || hr->next_marked_bytes() > 0) {
358 _helper.set_bit_for_region(hr);
359 }
360 return false;
361 }
362 };
363
364 G1CMBitMap* _bitmap;
365
366 G1CardLiveData* _live_data;
367
368 public:
369 G1FinalizeCardLiveDataTask(G1CMBitMap* bitmap, G1CardLiveData* live_data, uint n_workers) :
370 G1ParallelizeByRegionsTask("G1 Finalize Card Live Data", n_workers),
371 _bitmap(bitmap),
372 _live_data(live_data) {
373 }
374
375 void work(uint worker_id) {
376 G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data);
377 all_heap_regions_work(&cl, worker_id);
378 }
379 };
380
381 void G1CardLiveData::finalize(WorkGang* workers, G1CMBitMap* mark_bitmap) {
382 // Finalize the live data.
383 G1FinalizeCardLiveDataTask cl(mark_bitmap,
384 this,
385 workers->active_workers());
386 workers->run_task(&cl);
387 }
388
389 class G1ClearCardLiveDataTask : public AbstractGangTask {
390 BitMapView _bitmap;
391 size_t _num_chunks;
392 size_t _cur_chunk;
393 public:
394 G1ClearCardLiveDataTask(const BitMapView& bitmap, size_t num_tasks) :
395 AbstractGangTask("G1 Clear Card Live Data"),
396 _bitmap(bitmap),
397 _num_chunks(num_tasks),
413 }
414 }
415 };
416
417 void G1CardLiveData::clear(WorkGang* workers) {
418 guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
419
420 size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
421 uint const num_workers = (uint)MIN2(num_chunks, (size_t)workers->active_workers());
422
423 G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
424
425 log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks);
426 workers->run_task(&cl, num_workers);
427
428 // The region live bitmap is always very small, even for huge heaps. Clear
429 // directly.
430 live_regions_bm().clear();
431 }
432
433 class G1VerifyCardLiveDataTask: public G1ParallelizeByRegionsTask {
434 // Heap region closure used for verifying the live count data
435 // that was created concurrently and finalized during
436 // the remark pause. This closure is applied to the heap
437 // regions during the STW cleanup pause.
438 class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
439 private:
440 G1CollectedHeap* _g1h;
441 G1CMBitMap* _mark_bitmap;
442 G1CardLiveDataHelper _helper;
443
444 G1CardLiveData* _act_live_data;
445
446 G1CardLiveData* _exp_live_data;
447
448 int _failures;
449
450 // Completely recreates the live data count for the given heap region and
451 // returns the number of bytes marked.
452 size_t create_live_data_count(HeapRegion* hr) {
453 size_t bytes_marked = _helper.mark_marked_during_marking(_mark_bitmap, hr);
514 }
515 }
516
517 _failures += failures;
518
519 // We could stop iteration over the heap when we
520 // find the first violating region by returning true.
521 return false;
522 }
523 };
524 protected:
525 G1CollectedHeap* _g1h;
526 G1CMBitMap* _mark_bitmap;
527
528 G1CardLiveData* _act_live_data;
529
530 G1CardLiveData _exp_live_data;
531
532 int _failures;
533
534 public:
535 G1VerifyCardLiveDataTask(G1CMBitMap* bitmap,
536 G1CardLiveData* act_live_data,
537 uint n_workers)
538 : G1ParallelizeByRegionsTask("G1 Verify Card Live Data", n_workers),
539 _g1h(G1CollectedHeap::heap()),
540 _mark_bitmap(bitmap),
541 _act_live_data(act_live_data),
542 _exp_live_data(),
543 _failures(0) {
544 assert(VerifyDuringGC, "don't call this otherwise");
545 _exp_live_data.initialize(_g1h->max_capacity(), _g1h->max_regions());
546 }
547
548 void work(uint worker_id) {
549 G1VerifyCardLiveDataClosure cl(_g1h,
550 _mark_bitmap,
551 _act_live_data,
552 &_exp_live_data);
553 all_heap_regions_work(&cl, worker_id);
554
555 Atomic::add(cl.failures(), &_failures);
556 }
557
558 int failures() const { return _failures; }
559 };
560
561 void G1CardLiveData::verify(WorkGang* workers, G1CMBitMap* actual_bitmap) {
562 ResourceMark rm;
563
564 G1VerifyCardLiveDataTask cl(actual_bitmap,
565 this,
566 workers->active_workers());
567 workers->run_task(&cl);
568
569 guarantee(cl.failures() == 0, "Unexpected accounting failures");
570 }
571
572 #ifndef PRODUCT
573 void G1CardLiveData::verify_is_clear() {
|