src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 2314
f95d63e2154a
child 3156
f08d439fab8c
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

     1 /*
     2  * Copyright (c) 2005, 2010, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
    27 #include "gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp"
    28 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
    29 #include "oops/oop.inline.hpp"
    30 #include "runtime/os.hpp"
    31 #include "utilities/bitMap.inline.hpp"
    32 #ifdef TARGET_OS_FAMILY_linux
    33 # include "os_linux.inline.hpp"
    34 #endif
    35 #ifdef TARGET_OS_FAMILY_solaris
    36 # include "os_solaris.inline.hpp"
    37 #endif
    38 #ifdef TARGET_OS_FAMILY_windows
    39 # include "os_windows.inline.hpp"
    40 #endif
    42 bool
    43 ParMarkBitMap::initialize(MemRegion covered_region)
    44 {
    45   const idx_t bits = bits_required(covered_region);
    46   // The bits will be divided evenly between two bitmaps; each of them should be
    47   // an integral number of words.
    48   assert(bits % (BitsPerWord * 2) == 0, "region size unaligned");
    50   const size_t words = bits / BitsPerWord;
    51   const size_t raw_bytes = words * sizeof(idx_t);
    52   const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
    53   const size_t granularity = os::vm_allocation_granularity();
    54   const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
    56   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
    57     MAX2(page_sz, granularity);
    58   ReservedSpace rs(bytes, rs_align, rs_align > 0);
    59   os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
    60                        rs.base(), rs.size());
    61   _virtual_space = new PSVirtualSpace(rs, page_sz);
    62   if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
    63     _region_start = covered_region.start();
    64     _region_size = covered_region.word_size();
    65     idx_t* map = (idx_t*)_virtual_space->reserved_low_addr();
    66     _beg_bits.set_map(map);
    67     _beg_bits.set_size(bits / 2);
    68     _end_bits.set_map(map + words / 2);
    69     _end_bits.set_size(bits / 2);
    70     return true;
    71   }
    73   _region_start = 0;
    74   _region_size = 0;
    75   if (_virtual_space != NULL) {
    76     delete _virtual_space;
    77     _virtual_space = NULL;
    78     // Release memory reserved in the space.
    79     rs.release();
    80   }
    81   return false;
    82 }
    84 #ifdef ASSERT
    85 extern size_t mark_bitmap_count;
    86 extern size_t mark_bitmap_size;
    87 #endif  // #ifdef ASSERT
    89 bool
    90 ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
    91 {
    92   const idx_t beg_bit = addr_to_bit(addr);
    93   if (_beg_bits.par_set_bit(beg_bit)) {
    94     const idx_t end_bit = addr_to_bit(addr + size - 1);
    95     bool end_bit_ok = _end_bits.par_set_bit(end_bit);
    96     assert(end_bit_ok, "concurrency problem");
    97     DEBUG_ONLY(Atomic::inc_ptr(&mark_bitmap_count));
    98     DEBUG_ONLY(Atomic::add_ptr(size, &mark_bitmap_size));
    99     return true;
   100   }
   101   return false;
   102 }
   104 size_t
   105 ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const
   106 {
   107   assert(beg_addr <= end_addr, "bad range");
   109   idx_t live_bits = 0;
   111   // The bitmap routines require the right boundary to be word-aligned.
   112   const idx_t end_bit = addr_to_bit(end_addr);
   113   const idx_t range_end = BitMap::word_align_up(end_bit);
   115   idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
   116   while (beg_bit < end_bit) {
   117     idx_t tmp_end = find_obj_end(beg_bit, range_end);
   118     if (tmp_end < end_bit) {
   119       live_bits += tmp_end - beg_bit + 1;
   120       beg_bit = find_obj_beg(tmp_end + 1, range_end);
   121     } else {
   122       live_bits += end_bit - beg_bit;  // No + 1 here; end_bit is not counted.
   123       return bits_to_words(live_bits);
   124     }
   125   }
   126   return bits_to_words(live_bits);
   127 }
   129 size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
   130 {
   131   assert(beg_addr <= (HeapWord*)end_obj, "bad range");
   132   assert(is_marked(end_obj), "end_obj must be live");
   134   idx_t live_bits = 0;
   136   // The bitmap routines require the right boundary to be word-aligned.
   137   const idx_t end_bit = addr_to_bit((HeapWord*)end_obj);
   138   const idx_t range_end = BitMap::word_align_up(end_bit);
   140   idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
   141   while (beg_bit < end_bit) {
   142     idx_t tmp_end = find_obj_end(beg_bit, range_end);
   143     assert(tmp_end < end_bit, "missing end bit");
   144     live_bits += tmp_end - beg_bit + 1;
   145     beg_bit = find_obj_beg(tmp_end + 1, range_end);
   146   }
   147   return bits_to_words(live_bits);
   148 }
   150 ParMarkBitMap::IterationStatus
   151 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
   152                        idx_t range_beg, idx_t range_end) const
   153 {
   154   DEBUG_ONLY(verify_bit(range_beg);)
   155   DEBUG_ONLY(verify_bit(range_end);)
   156   assert(range_beg <= range_end, "live range invalid");
   158   // The bitmap routines require the right boundary to be word-aligned.
   159   const idx_t search_end = BitMap::word_align_up(range_end);
   161   idx_t cur_beg = find_obj_beg(range_beg, search_end);
   162   while (cur_beg < range_end) {
   163     const idx_t cur_end = find_obj_end(cur_beg, search_end);
   164     if (cur_end >= range_end) {
   165       // The obj ends outside the range.
   166       live_closure->set_source(bit_to_addr(cur_beg));
   167       return incomplete;
   168     }
   170     const size_t size = obj_size(cur_beg, cur_end);
   171     IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
   172     if (status != incomplete) {
   173       assert(status == would_overflow || status == full, "sanity");
   174       return status;
   175     }
   177     // Successfully processed the object; look for the next object.
   178     cur_beg = find_obj_beg(cur_end + 1, search_end);
   179   }
   181   live_closure->set_source(bit_to_addr(range_end));
   182   return complete;
   183 }
   185 ParMarkBitMap::IterationStatus
   186 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
   187                        ParMarkBitMapClosure* dead_closure,
   188                        idx_t range_beg, idx_t range_end,
   189                        idx_t dead_range_end) const
   190 {
   191   DEBUG_ONLY(verify_bit(range_beg);)
   192   DEBUG_ONLY(verify_bit(range_end);)
   193   DEBUG_ONLY(verify_bit(dead_range_end);)
   194   assert(range_beg <= range_end, "live range invalid");
   195   assert(range_end <= dead_range_end, "dead range invalid");
   197   // The bitmap routines require the right boundary to be word-aligned.
   198   const idx_t live_search_end = BitMap::word_align_up(range_end);
   199   const idx_t dead_search_end = BitMap::word_align_up(dead_range_end);
   201   idx_t cur_beg = range_beg;
   202   if (range_beg < range_end && is_unmarked(range_beg)) {
   203     // The range starts with dead space.  Look for the next object, then fill.
   204     cur_beg = find_obj_beg(range_beg + 1, dead_search_end);
   205     const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
   206     const size_t size = obj_size(range_beg, dead_space_end);
   207     dead_closure->do_addr(bit_to_addr(range_beg), size);
   208   }
   210   while (cur_beg < range_end) {
   211     const idx_t cur_end = find_obj_end(cur_beg, live_search_end);
   212     if (cur_end >= range_end) {
   213       // The obj ends outside the range.
   214       live_closure->set_source(bit_to_addr(cur_beg));
   215       return incomplete;
   216     }
   218     const size_t size = obj_size(cur_beg, cur_end);
   219     IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
   220     if (status != incomplete) {
   221       assert(status == would_overflow || status == full, "sanity");
   222       return status;
   223     }
   225     // Look for the start of the next object.
   226     const idx_t dead_space_beg = cur_end + 1;
   227     cur_beg = find_obj_beg(dead_space_beg, dead_search_end);
   228     if (cur_beg > dead_space_beg) {
   229       // Found dead space; compute the size and invoke the dead closure.
   230       const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
   231       const size_t size = obj_size(dead_space_beg, dead_space_end);
   232       dead_closure->do_addr(bit_to_addr(dead_space_beg), size);
   233     }
   234   }
   236   live_closure->set_source(bit_to_addr(range_end));
   237   return complete;
   238 }
   240 #ifndef PRODUCT
   241 void ParMarkBitMap::reset_counters()
   242 {
   243   _cas_tries = _cas_retries = _cas_by_another = 0;
   244 }
   245 #endif  // #ifndef PRODUCT
   247 #ifdef ASSERT
   248 void ParMarkBitMap::verify_clear() const
   249 {
   250   const idx_t* const beg = (const idx_t*)_virtual_space->committed_low_addr();
   251   const idx_t* const end = (const idx_t*)_virtual_space->committed_high_addr();
   252   for (const idx_t* p = beg; p < end; ++p) {
   253     assert(*p == 0, "bitmap not clear");
   254   }
   255 }
   256 #endif  // #ifdef ASSERT

mercurial