src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.inline.hpp
branchaefimov-dns-client-branch
changeset 59099 fcdb8e7ead8f
parent 58984 15e026239a6c
parent 59075 355f4f42dda5
child 59100 b92aac38b046
equal deleted inserted replaced
58984:15e026239a6c 59099:fcdb8e7ead8f
     1 /*
       
     2  * Copyright (c) 2001, 2019, 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  *
       
    23  */
       
    24 
       
    25 #ifndef SHARE_GC_CMS_CONCURRENTMARKSWEEPGENERATION_INLINE_HPP
       
    26 #define SHARE_GC_CMS_CONCURRENTMARKSWEEPGENERATION_INLINE_HPP
       
    27 
       
    28 #include "gc/cms/cmsHeap.hpp"
       
    29 #include "gc/cms/cmsLockVerifier.hpp"
       
    30 #include "gc/cms/compactibleFreeListSpace.inline.hpp"
       
    31 #include "gc/cms/concurrentMarkSweepGeneration.hpp"
       
    32 #include "gc/cms/concurrentMarkSweepThread.hpp"
       
    33 #include "gc/cms/parNewGeneration.hpp"
       
    34 #include "gc/shared/gcUtil.hpp"
       
    35 #include "utilities/align.hpp"
       
    36 #include "utilities/bitMap.inline.hpp"
       
    37 
       
    38 inline void CMSBitMap::clear_all() {
       
    39   assert_locked();
       
    40   // CMS bitmaps are usually cover large memory regions
       
    41   _bm.clear_large();
       
    42   return;
       
    43 }
       
    44 
       
    45 inline size_t CMSBitMap::heapWordToOffset(HeapWord* addr) const {
       
    46   return (pointer_delta(addr, _bmStartWord)) >> _shifter;
       
    47 }
       
    48 
       
    49 inline HeapWord* CMSBitMap::offsetToHeapWord(size_t offset) const {
       
    50   return _bmStartWord + (offset << _shifter);
       
    51 }
       
    52 
       
    53 inline size_t CMSBitMap::heapWordDiffToOffsetDiff(size_t diff) const {
       
    54   assert((diff & ((1 << _shifter) - 1)) == 0, "argument check");
       
    55   return diff >> _shifter;
       
    56 }
       
    57 
       
    58 inline void CMSBitMap::mark(HeapWord* addr) {
       
    59   assert_locked();
       
    60   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
    61          "outside underlying space?");
       
    62   _bm.set_bit(heapWordToOffset(addr));
       
    63 }
       
    64 
       
    65 inline bool CMSBitMap::par_mark(HeapWord* addr) {
       
    66   assert_locked();
       
    67   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
    68          "outside underlying space?");
       
    69   return _bm.par_at_put(heapWordToOffset(addr), true);
       
    70 }
       
    71 
       
    72 inline void CMSBitMap::par_clear(HeapWord* addr) {
       
    73   assert_locked();
       
    74   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
    75          "outside underlying space?");
       
    76   _bm.par_at_put(heapWordToOffset(addr), false);
       
    77 }
       
    78 
       
    79 inline void CMSBitMap::mark_range(MemRegion mr) {
       
    80   NOT_PRODUCT(region_invariant(mr));
       
    81   // Range size is usually just 1 bit.
       
    82   _bm.set_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
    83                 BitMap::small_range);
       
    84 }
       
    85 
       
    86 inline void CMSBitMap::clear_range(MemRegion mr) {
       
    87   NOT_PRODUCT(region_invariant(mr));
       
    88   // Range size is usually just 1 bit.
       
    89   _bm.clear_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
    90                   BitMap::small_range);
       
    91 }
       
    92 
       
    93 inline void CMSBitMap::par_mark_range(MemRegion mr) {
       
    94   NOT_PRODUCT(region_invariant(mr));
       
    95   // Range size is usually just 1 bit.
       
    96   _bm.par_set_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
    97                     BitMap::small_range);
       
    98 }
       
    99 
       
   100 inline void CMSBitMap::par_clear_range(MemRegion mr) {
       
   101   NOT_PRODUCT(region_invariant(mr));
       
   102   // Range size is usually just 1 bit.
       
   103   _bm.par_clear_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
   104                       BitMap::small_range);
       
   105 }
       
   106 
       
   107 inline void CMSBitMap::mark_large_range(MemRegion mr) {
       
   108   NOT_PRODUCT(region_invariant(mr));
       
   109   // Range size must be greater than 32 bytes.
       
   110   _bm.set_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
   111                 BitMap::large_range);
       
   112 }
       
   113 
       
   114 inline void CMSBitMap::clear_large_range(MemRegion mr) {
       
   115   NOT_PRODUCT(region_invariant(mr));
       
   116   // Range size must be greater than 32 bytes.
       
   117   _bm.clear_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
   118                   BitMap::large_range);
       
   119 }
       
   120 
       
   121 inline void CMSBitMap::par_mark_large_range(MemRegion mr) {
       
   122   NOT_PRODUCT(region_invariant(mr));
       
   123   // Range size must be greater than 32 bytes.
       
   124   _bm.par_set_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
   125                     BitMap::large_range);
       
   126 }
       
   127 
       
   128 inline void CMSBitMap::par_clear_large_range(MemRegion mr) {
       
   129   NOT_PRODUCT(region_invariant(mr));
       
   130   // Range size must be greater than 32 bytes.
       
   131   _bm.par_clear_range(heapWordToOffset(mr.start()), heapWordToOffset(mr.end()),
       
   132                       BitMap::large_range);
       
   133 }
       
   134 
       
   135 // Starting at "addr" (inclusive) return a memory region
       
   136 // corresponding to the first maximally contiguous marked ("1") region.
       
   137 inline MemRegion CMSBitMap::getAndClearMarkedRegion(HeapWord* addr) {
       
   138   return getAndClearMarkedRegion(addr, endWord());
       
   139 }
       
   140 
       
   141 // Starting at "start_addr" (inclusive) return a memory region
       
   142 // corresponding to the first maximal contiguous marked ("1") region
       
   143 // strictly less than end_addr.
       
   144 inline MemRegion CMSBitMap::getAndClearMarkedRegion(HeapWord* start_addr,
       
   145                                                     HeapWord* end_addr) {
       
   146   HeapWord *start, *end;
       
   147   assert_locked();
       
   148   start = getNextMarkedWordAddress  (start_addr, end_addr);
       
   149   end   = getNextUnmarkedWordAddress(start,      end_addr);
       
   150   assert(start <= end, "Consistency check");
       
   151   MemRegion mr(start, end);
       
   152   if (!mr.is_empty()) {
       
   153     clear_range(mr);
       
   154   }
       
   155   return mr;
       
   156 }
       
   157 
       
   158 inline bool CMSBitMap::isMarked(HeapWord* addr) const {
       
   159   assert_locked();
       
   160   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
   161          "outside underlying space?");
       
   162   return _bm.at(heapWordToOffset(addr));
       
   163 }
       
   164 
       
   165 // The same as isMarked() but without a lock check.
       
   166 inline bool CMSBitMap::par_isMarked(HeapWord* addr) const {
       
   167   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
   168          "outside underlying space?");
       
   169   return _bm.at(heapWordToOffset(addr));
       
   170 }
       
   171 
       
   172 
       
   173 inline bool CMSBitMap::isUnmarked(HeapWord* addr) const {
       
   174   assert_locked();
       
   175   assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
       
   176          "outside underlying space?");
       
   177   return !_bm.at(heapWordToOffset(addr));
       
   178 }
       
   179 
       
   180 // Return the HeapWord address corresponding to next "1" bit
       
   181 // (inclusive).
       
   182 inline HeapWord* CMSBitMap::getNextMarkedWordAddress(HeapWord* addr) const {
       
   183   return getNextMarkedWordAddress(addr, endWord());
       
   184 }
       
   185 
       
   186 // Return the least HeapWord address corresponding to next "1" bit
       
   187 // starting at start_addr (inclusive) but strictly less than end_addr.
       
   188 inline HeapWord* CMSBitMap::getNextMarkedWordAddress(
       
   189   HeapWord* start_addr, HeapWord* end_addr) const {
       
   190   assert_locked();
       
   191   size_t nextOffset = _bm.get_next_one_offset(
       
   192                         heapWordToOffset(start_addr),
       
   193                         heapWordToOffset(end_addr));
       
   194   HeapWord* nextAddr = offsetToHeapWord(nextOffset);
       
   195   assert(nextAddr >= start_addr &&
       
   196          nextAddr <= end_addr, "get_next_one postcondition");
       
   197   assert((nextAddr == end_addr) ||
       
   198          isMarked(nextAddr), "get_next_one postcondition");
       
   199   return nextAddr;
       
   200 }
       
   201 
       
   202 
       
   203 // Return the HeapWord address corresponding to the next "0" bit
       
   204 // (inclusive).
       
   205 inline HeapWord* CMSBitMap::getNextUnmarkedWordAddress(HeapWord* addr) const {
       
   206   return getNextUnmarkedWordAddress(addr, endWord());
       
   207 }
       
   208 
       
   209 // Return the HeapWord address corresponding to the next "0" bit
       
   210 // (inclusive).
       
   211 inline HeapWord* CMSBitMap::getNextUnmarkedWordAddress(
       
   212   HeapWord* start_addr, HeapWord* end_addr) const {
       
   213   assert_locked();
       
   214   size_t nextOffset = _bm.get_next_zero_offset(
       
   215                         heapWordToOffset(start_addr),
       
   216                         heapWordToOffset(end_addr));
       
   217   HeapWord* nextAddr = offsetToHeapWord(nextOffset);
       
   218   assert(nextAddr >= start_addr &&
       
   219          nextAddr <= end_addr, "get_next_zero postcondition");
       
   220   assert((nextAddr == end_addr) ||
       
   221           isUnmarked(nextAddr), "get_next_zero postcondition");
       
   222   return nextAddr;
       
   223 }
       
   224 
       
   225 inline bool CMSBitMap::isAllClear() const {
       
   226   assert_locked();
       
   227   return getNextMarkedWordAddress(startWord()) >= endWord();
       
   228 }
       
   229 
       
   230 inline void CMSBitMap::iterate(BitMapClosure* cl, HeapWord* left,
       
   231                             HeapWord* right) {
       
   232   assert_locked();
       
   233   left = MAX2(_bmStartWord, left);
       
   234   right = MIN2(_bmStartWord + _bmWordSize, right);
       
   235   if (right > left) {
       
   236     _bm.iterate(cl, heapWordToOffset(left), heapWordToOffset(right));
       
   237   }
       
   238 }
       
   239 
       
   240 inline void CMSCollector::save_sweep_limits() {
       
   241   _cmsGen->save_sweep_limit();
       
   242 }
       
   243 
       
   244 inline bool CMSCollector::is_dead_obj(oop obj) const {
       
   245   HeapWord* addr = (HeapWord*)obj;
       
   246   assert((_cmsGen->cmsSpace()->is_in_reserved(addr)
       
   247           && _cmsGen->cmsSpace()->block_is_obj(addr)),
       
   248          "must be object");
       
   249   return  should_unload_classes() &&
       
   250           _collectorState == Sweeping &&
       
   251          !_markBitMap.isMarked(addr);
       
   252 }
       
   253 
       
   254 inline bool CMSCollector::should_abort_preclean() const {
       
   255   // We are in the midst of an "abortable preclean" and either
       
   256   // scavenge is done or foreground GC wants to take over collection
       
   257   return _collectorState == AbortablePreclean &&
       
   258          (_abort_preclean || _foregroundGCIsActive ||
       
   259           CMSHeap::heap()->incremental_collection_will_fail(true /* consult_young */));
       
   260 }
       
   261 
       
   262 inline size_t CMSCollector::get_eden_used() const {
       
   263   return _young_gen->eden()->used();
       
   264 }
       
   265 
       
   266 inline size_t CMSCollector::get_eden_capacity() const {
       
   267   return _young_gen->eden()->capacity();
       
   268 }
       
   269 
       
   270 inline bool CMSStats::valid() const {
       
   271   return _valid_bits == _ALL_VALID;
       
   272 }
       
   273 
       
   274 inline void CMSStats::record_gc0_begin() {
       
   275   if (_gc0_begin_time.is_updated()) {
       
   276     float last_gc0_period = _gc0_begin_time.seconds();
       
   277     _gc0_period = AdaptiveWeightedAverage::exp_avg(_gc0_period,
       
   278       last_gc0_period, _gc0_alpha);
       
   279     _gc0_alpha = _saved_alpha;
       
   280     _valid_bits |= _GC0_VALID;
       
   281   }
       
   282   _cms_used_at_gc0_begin = _cms_gen->cmsSpace()->used();
       
   283 
       
   284   _gc0_begin_time.update();
       
   285 }
       
   286 
       
   287 inline void CMSStats::record_gc0_end(size_t cms_gen_bytes_used) {
       
   288   float last_gc0_duration = _gc0_begin_time.seconds();
       
   289   _gc0_duration = AdaptiveWeightedAverage::exp_avg(_gc0_duration,
       
   290     last_gc0_duration, _gc0_alpha);
       
   291 
       
   292   // Amount promoted.
       
   293   _cms_used_at_gc0_end = cms_gen_bytes_used;
       
   294 
       
   295   size_t promoted_bytes = 0;
       
   296   if (_cms_used_at_gc0_end >= _cms_used_at_gc0_begin) {
       
   297     promoted_bytes = _cms_used_at_gc0_end - _cms_used_at_gc0_begin;
       
   298   }
       
   299 
       
   300   // If the young gen collection was skipped, then the
       
   301   // number of promoted bytes will be 0 and adding it to the
       
   302   // average will incorrectly lessen the average.  It is, however,
       
   303   // also possible that no promotion was needed.
       
   304   //
       
   305   // _gc0_promoted used to be calculated as
       
   306   // _gc0_promoted = AdaptiveWeightedAverage::exp_avg(_gc0_promoted,
       
   307   //  promoted_bytes, _gc0_alpha);
       
   308   _cms_gen->gc_stats()->avg_promoted()->sample(promoted_bytes);
       
   309   _gc0_promoted = (size_t) _cms_gen->gc_stats()->avg_promoted()->average();
       
   310 
       
   311   // Amount directly allocated.
       
   312   size_t allocated_bytes = _cms_gen->direct_allocated_words() * HeapWordSize;
       
   313   _cms_gen->reset_direct_allocated_words();
       
   314   _cms_allocated = AdaptiveWeightedAverage::exp_avg(_cms_allocated,
       
   315     allocated_bytes, _gc0_alpha);
       
   316 }
       
   317 
       
   318 inline void CMSStats::record_cms_begin() {
       
   319   _cms_timer.stop();
       
   320 
       
   321   // This is just an approximate value, but is good enough.
       
   322   _cms_used_at_cms_begin = _cms_used_at_gc0_end;
       
   323 
       
   324   _cms_period = AdaptiveWeightedAverage::exp_avg((float)_cms_period,
       
   325     (float) _cms_timer.seconds(), _cms_alpha);
       
   326   _cms_begin_time.update();
       
   327 
       
   328   _cms_timer.reset();
       
   329   _cms_timer.start();
       
   330 }
       
   331 
       
   332 inline void CMSStats::record_cms_end() {
       
   333   _cms_timer.stop();
       
   334 
       
   335   float cur_duration = _cms_timer.seconds();
       
   336   _cms_duration = AdaptiveWeightedAverage::exp_avg(_cms_duration,
       
   337     cur_duration, _cms_alpha);
       
   338 
       
   339   _cms_end_time.update();
       
   340   _cms_alpha = _saved_alpha;
       
   341   _allow_duty_cycle_reduction = true;
       
   342   _valid_bits |= _CMS_VALID;
       
   343 
       
   344   _cms_timer.start();
       
   345 }
       
   346 
       
   347 inline double CMSStats::cms_time_since_begin() const {
       
   348   return _cms_begin_time.seconds();
       
   349 }
       
   350 
       
   351 inline double CMSStats::cms_time_since_end() const {
       
   352   return _cms_end_time.seconds();
       
   353 }
       
   354 
       
   355 inline double CMSStats::promotion_rate() const {
       
   356   assert(valid(), "statistics not valid yet");
       
   357   return gc0_promoted() / gc0_period();
       
   358 }
       
   359 
       
   360 inline double CMSStats::cms_allocation_rate() const {
       
   361   assert(valid(), "statistics not valid yet");
       
   362   return cms_allocated() / gc0_period();
       
   363 }
       
   364 
       
   365 inline double CMSStats::cms_consumption_rate() const {
       
   366   assert(valid(), "statistics not valid yet");
       
   367   return (gc0_promoted() + cms_allocated()) / gc0_period();
       
   368 }
       
   369 
       
   370 inline void ConcurrentMarkSweepGeneration::save_sweep_limit() {
       
   371   cmsSpace()->save_sweep_limit();
       
   372 }
       
   373 
       
   374 inline MemRegion ConcurrentMarkSweepGeneration::used_region_at_save_marks() const {
       
   375   return _cmsSpace->used_region_at_save_marks();
       
   376 }
       
   377 
       
   378 template <typename OopClosureType>
       
   379 void ConcurrentMarkSweepGeneration::oop_since_save_marks_iterate(OopClosureType* cl) {
       
   380   cl->set_generation(this);
       
   381   cmsSpace()->oop_since_save_marks_iterate(cl);
       
   382   cl->reset_generation();
       
   383   save_marks();
       
   384 }
       
   385 
       
   386 inline void MarkFromRootsClosure::do_yield_check() {
       
   387   if (ConcurrentMarkSweepThread::should_yield() &&
       
   388       !_collector->foregroundGCIsActive() &&
       
   389       _yield) {
       
   390     do_yield_work();
       
   391   }
       
   392 }
       
   393 
       
   394 inline void ParMarkFromRootsClosure::do_yield_check() {
       
   395   if (ConcurrentMarkSweepThread::should_yield() &&
       
   396       !_collector->foregroundGCIsActive()) {
       
   397     do_yield_work();
       
   398   }
       
   399 }
       
   400 
       
   401 inline void PushOrMarkClosure::do_yield_check() {
       
   402   _parent->do_yield_check();
       
   403 }
       
   404 
       
   405 inline void ParPushOrMarkClosure::do_yield_check() {
       
   406   _parent->do_yield_check();
       
   407 }
       
   408 
       
   409 // Return value of "true" indicates that the on-going preclean
       
   410 // should be aborted.
       
   411 inline bool ScanMarkedObjectsAgainCarefullyClosure::do_yield_check() {
       
   412   if (ConcurrentMarkSweepThread::should_yield() &&
       
   413       !_collector->foregroundGCIsActive() &&
       
   414       _yield) {
       
   415     // Sample young gen size before and after yield
       
   416     _collector->sample_eden();
       
   417     do_yield_work();
       
   418     _collector->sample_eden();
       
   419     return _collector->should_abort_preclean();
       
   420   }
       
   421   return false;
       
   422 }
       
   423 
       
   424 inline void SurvivorSpacePrecleanClosure::do_yield_check() {
       
   425   if (ConcurrentMarkSweepThread::should_yield() &&
       
   426       !_collector->foregroundGCIsActive() &&
       
   427       _yield) {
       
   428     // Sample young gen size before and after yield
       
   429     _collector->sample_eden();
       
   430     do_yield_work();
       
   431     _collector->sample_eden();
       
   432   }
       
   433 }
       
   434 
       
   435 inline void SweepClosure::do_yield_check(HeapWord* addr) {
       
   436   if (ConcurrentMarkSweepThread::should_yield() &&
       
   437       !_collector->foregroundGCIsActive() &&
       
   438       _yield) {
       
   439     do_yield_work(addr);
       
   440   }
       
   441 }
       
   442 
       
   443 inline void MarkRefsIntoAndScanClosure::do_yield_check() {
       
   444   // The conditions are ordered for the remarking phase
       
   445   // when _yield is false.
       
   446   if (_yield &&
       
   447       !_collector->foregroundGCIsActive() &&
       
   448       ConcurrentMarkSweepThread::should_yield()) {
       
   449     do_yield_work();
       
   450   }
       
   451 }
       
   452 
       
   453 
       
   454 inline void ModUnionClosure::do_MemRegion(MemRegion mr) {
       
   455   // Align the end of mr so it's at a card boundary.
       
   456   // This is superfluous except at the end of the space;
       
   457   // we should do better than this XXX
       
   458   MemRegion mr2(mr.start(), align_up(mr.end(),
       
   459                 CardTable::card_size /* bytes */));
       
   460   _t->mark_range(mr2);
       
   461 }
       
   462 
       
   463 inline void ModUnionClosurePar::do_MemRegion(MemRegion mr) {
       
   464   // Align the end of mr so it's at a card boundary.
       
   465   // This is superfluous except at the end of the space;
       
   466   // we should do better than this XXX
       
   467   MemRegion mr2(mr.start(), align_up(mr.end(),
       
   468                 CardTable::card_size /* bytes */));
       
   469   _t->par_mark_range(mr2);
       
   470 }
       
   471 
       
   472 #endif // SHARE_GC_CMS_CONCURRENTMARKSWEEPGENERATION_INLINE_HPP