rev 9846 : [mq]: par-scav-patch
rev 9847 : 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value.
Reviewed-by: tschatzl, mgerdin
Contributed-by: ray alex <sky1young@gmail.com>

   1 /*
   2  * Copyright (c) 2005, 2015, 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 #include "precompiled.hpp"
  26 #include "gc/parallel/parMarkBitMap.hpp"

  27 #include "gc/parallel/psParallelCompact.hpp"
  28 #include "oops/oop.inline.hpp"
  29 #include "runtime/atomic.inline.hpp"
  30 #include "runtime/os.hpp"
  31 #include "services/memTracker.hpp"
  32 #include "utilities/bitMap.inline.hpp"
  33 
  34 bool
  35 ParMarkBitMap::initialize(MemRegion covered_region)
  36 {
  37   const idx_t bits = bits_required(covered_region);
  38   // The bits will be divided evenly between two bitmaps; each of them should be
  39   // an integral number of words.
  40   assert(bits % (BitsPerWord * 2) == 0, "region size unaligned");
  41 
  42   const size_t words = bits / BitsPerWord;
  43   const size_t raw_bytes = words * sizeof(idx_t);
  44   const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10);
  45   const size_t granularity = os::vm_allocation_granularity();
  46   _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
  47 
  48   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
  49     MAX2(page_sz, granularity);
  50   ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
  51   os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
  52                        rs.base(), rs.size());
  53 
  54   MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
  55 
  56   _virtual_space = new PSVirtualSpace(rs, page_sz);
  57   if (_virtual_space != NULL && _virtual_space->expand_by(_reserved_byte_size)) {
  58     _region_start = covered_region.start();
  59     _region_size = covered_region.word_size();
  60     BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr();
  61     _beg_bits.set_map(map);
  62     _beg_bits.set_size(bits / 2);
  63     _end_bits.set_map(map + words / 2);
  64     _end_bits.set_size(bits / 2);
  65     return true;
  66   }
  67 
  68   _region_start = 0;
  69   _region_size = 0;
  70   if (_virtual_space != NULL) {
  71     delete _virtual_space;
  72     _virtual_space = NULL;
  73     // Release memory reserved in the space.
  74     rs.release();
  75   }
  76   return false;
  77 }
  78 
  79 #ifdef ASSERT
  80 extern size_t mark_bitmap_count;
  81 extern size_t mark_bitmap_size;
  82 #endif  // #ifdef ASSERT
  83 
  84 bool
  85 ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
  86 {
  87   const idx_t beg_bit = addr_to_bit(addr);
  88   if (_beg_bits.par_set_bit(beg_bit)) {
  89     const idx_t end_bit = addr_to_bit(addr + size - 1);
  90     bool end_bit_ok = _end_bits.par_set_bit(end_bit);
  91     assert(end_bit_ok, "concurrency problem");
  92     DEBUG_ONLY(Atomic::inc_ptr(&mark_bitmap_count));
  93     DEBUG_ONLY(Atomic::add_ptr(size, &mark_bitmap_size));
  94     return true;
  95   }
  96   return false;
  97 }
  98 
  99 size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const













 100 {
 101   assert(beg_addr <= (HeapWord*)end_obj, "bad range");
 102   assert(is_marked(end_obj), "end_obj must be live");
 103 
 104   idx_t live_bits = 0;
 105 
 106   // The bitmap routines require the right boundary to be word-aligned.
 107   const idx_t end_bit = addr_to_bit((HeapWord*)end_obj);
 108   const idx_t range_end = BitMap::word_align_up(end_bit);
 109 
 110   idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
 111   while (beg_bit < end_bit) {
 112     idx_t tmp_end = find_obj_end(beg_bit, range_end);
 113     assert(tmp_end < end_bit, "missing end bit");
 114     live_bits += tmp_end - beg_bit + 1;
 115     beg_bit = find_obj_beg(tmp_end + 1, range_end);
 116   }
 117   return bits_to_words(live_bits);


































 118 }
 119 
 120 ParMarkBitMap::IterationStatus
 121 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
 122                        idx_t range_beg, idx_t range_end) const
 123 {
 124   DEBUG_ONLY(verify_bit(range_beg);)
 125   DEBUG_ONLY(verify_bit(range_end);)
 126   assert(range_beg <= range_end, "live range invalid");
 127 
 128   // The bitmap routines require the right boundary to be word-aligned.
 129   const idx_t search_end = BitMap::word_align_up(range_end);
 130 
 131   idx_t cur_beg = find_obj_beg(range_beg, search_end);
 132   while (cur_beg < range_end) {
 133     const idx_t cur_end = find_obj_end(cur_beg, search_end);
 134     if (cur_end >= range_end) {
 135       // The obj ends outside the range.
 136       live_closure->set_source(bit_to_addr(cur_beg));
 137       return incomplete;
 138     }
 139 
 140     const size_t size = obj_size(cur_beg, cur_end);
 141     IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
 142     if (status != incomplete) {
 143       assert(status == would_overflow || status == full, "sanity");
 144       return status;
 145     }
 146 
 147     // Successfully processed the object; look for the next object.
 148     cur_beg = find_obj_beg(cur_end + 1, search_end);
 149   }
 150 
 151   live_closure->set_source(bit_to_addr(range_end));
 152   return complete;
 153 }
 154 
 155 ParMarkBitMap::IterationStatus
 156 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
 157                        ParMarkBitMapClosure* dead_closure,
 158                        idx_t range_beg, idx_t range_end,
 159                        idx_t dead_range_end) const
 160 {
 161   DEBUG_ONLY(verify_bit(range_beg);)
 162   DEBUG_ONLY(verify_bit(range_end);)
 163   DEBUG_ONLY(verify_bit(dead_range_end);)
 164   assert(range_beg <= range_end, "live range invalid");
 165   assert(range_end <= dead_range_end, "dead range invalid");
 166 
 167   // The bitmap routines require the right boundary to be word-aligned.
 168   const idx_t live_search_end = BitMap::word_align_up(range_end);
 169   const idx_t dead_search_end = BitMap::word_align_up(dead_range_end);
 170 
 171   idx_t cur_beg = range_beg;
 172   if (range_beg < range_end && is_unmarked(range_beg)) {
 173     // The range starts with dead space.  Look for the next object, then fill.
 174     cur_beg = find_obj_beg(range_beg + 1, dead_search_end);
 175     const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
 176     const size_t size = obj_size(range_beg, dead_space_end);
 177     dead_closure->do_addr(bit_to_addr(range_beg), size);
 178   }
 179 
 180   while (cur_beg < range_end) {
 181     const idx_t cur_end = find_obj_end(cur_beg, live_search_end);
 182     if (cur_end >= range_end) {
 183       // The obj ends outside the range.
 184       live_closure->set_source(bit_to_addr(cur_beg));
 185       return incomplete;
 186     }
 187 
 188     const size_t size = obj_size(cur_beg, cur_end);
 189     IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
 190     if (status != incomplete) {
 191       assert(status == would_overflow || status == full, "sanity");
 192       return status;
 193     }
 194 
 195     // Look for the start of the next object.
 196     const idx_t dead_space_beg = cur_end + 1;
 197     cur_beg = find_obj_beg(dead_space_beg, dead_search_end);
 198     if (cur_beg > dead_space_beg) {
 199       // Found dead space; compute the size and invoke the dead closure.
 200       const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
 201       const size_t size = obj_size(dead_space_beg, dead_space_end);
 202       dead_closure->do_addr(bit_to_addr(dead_space_beg), size);
 203     }
 204   }
 205 
 206   live_closure->set_source(bit_to_addr(range_end));
 207   return complete;
 208 }
 209 
 210 #ifdef ASSERT
 211 void ParMarkBitMap::verify_clear() const
 212 {
 213   const idx_t* const beg = (const idx_t*)_virtual_space->committed_low_addr();
 214   const idx_t* const end = (const idx_t*)_virtual_space->committed_high_addr();
 215   for (const idx_t* p = beg; p < end; ++p) {
 216     assert(*p == 0, "bitmap not clear");
 217   }
 218 }
 219 #endif  // #ifdef ASSERT
--- EOF ---