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