src/share/vm/gc/g1/g1CardLiveData.cpp

Print this page


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