1 /*
   2  * Copyright (c) 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 #ifndef SHARE_VM_GC_SHARED_CMBITMAP_INLINE_HPP
  26 #define SHARE_VM_GC_SHARED_CMBITMAP_INLINE_HPP
  27 
  28 #include "gc_implementation/shared/markBitMap.hpp"
  29 #include "utilities/bitMap.inline.hpp"
  30 
  31 inline HeapWord* MarkBitMapRO::getNextMarkedWordAddress(const HeapWord* addr,
  32                                                const HeapWord* limit) const {
  33   // First we must round addr *up* to a possible object boundary.
  34   addr = (HeapWord*)align_size_up((intptr_t)addr,
  35                                   HeapWordSize << _shifter);
  36   size_t addrOffset = heapWordToOffset(addr);
  37   assert(limit != NULL, "limit must not be NULL");
  38   size_t limitOffset = heapWordToOffset(limit);
  39   size_t nextOffset = _bm.get_next_one_offset(addrOffset, limitOffset);
  40   HeapWord* nextAddr = offsetToHeapWord(nextOffset);
  41   assert(nextAddr >= addr, "get_next_one postcondition");
  42   assert(nextAddr == limit || isMarked(nextAddr),
  43          "get_next_one postcondition");
  44   return nextAddr;
  45 }
  46 
  47 inline bool MarkBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
  48   HeapWord* start_addr = MAX2(startWord(), mr.start());
  49   HeapWord* end_addr = MIN2(endWord(), mr.end());
  50 
  51   if (end_addr > start_addr) {
  52     // Right-open interval [start-offset, end-offset).
  53     BitMap::idx_t start_offset = heapWordToOffset(start_addr);
  54     BitMap::idx_t end_offset = heapWordToOffset(end_addr);
  55 
  56     start_offset = _bm.get_next_one_offset(start_offset, end_offset);
  57     while (start_offset < end_offset) {
  58       if (!cl->do_bit(start_offset)) {
  59         return false;
  60       }
  61       HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
  62       BitMap::idx_t next_offset = heapWordToOffset(next_addr);
  63       start_offset = _bm.get_next_one_offset(next_offset, end_offset);
  64     }
  65   }
  66   return true;
  67 }
  68 
  69 // The argument addr should be the start address of a valid object
  70 HeapWord* MarkBitMapRO::nextObject(HeapWord* addr) {
  71   oop obj = (oop) addr;
  72   HeapWord* res =  addr + obj->size();
  73   assert(offsetToHeapWord(heapWordToOffset(res)) == res, "sanity");
  74   return res;
  75 }
  76 
  77 #define check_mark(addr)                                                       \
  78   assert(_bmStartWord <= (addr) && (addr) < (_bmStartWord + _bmWordSize),      \
  79          "outside underlying space?");                                         \
  80   /* assert(G1CollectedHeap::heap()->is_in_exact(addr),                  \
  81          err_msg("Trying to access not available bitmap "PTR_FORMAT            \
  82                  " corresponding to "PTR_FORMAT" (%u)",                        \
  83                  p2i(this), p2i(addr), G1CollectedHeap::heap()->addr_to_region(addr))); */
  84 
  85 inline void MarkBitMap::mark(HeapWord* addr) {
  86   check_mark(addr);
  87   _bm.set_bit(heapWordToOffset(addr));
  88 }
  89 
  90 inline void MarkBitMap::clear(HeapWord* addr) {
  91   check_mark(addr);
  92   _bm.clear_bit(heapWordToOffset(addr));
  93 }
  94 
  95 inline bool MarkBitMap::parMark(HeapWord* addr) {
  96   check_mark(addr);
  97   return _bm.par_set_bit(heapWordToOffset(addr));
  98 }
  99 
 100 #undef check_mark
 101 
 102 #endif // SHARE_VM_GC_SHARED_CMBITMAP_INLINE_HPP