1 /*
  2  * Copyright (c) 2017, 2024, 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_PARALLEL_PARMARKBITMAP_INLINE_HPP
 26 #define SHARE_GC_PARALLEL_PARMARKBITMAP_INLINE_HPP
 27 
 28 #include "gc/parallel/parMarkBitMap.hpp"
 29 
 30 #include "utilities/align.hpp"
 31 #include "utilities/bitMap.inline.hpp"
 32 
 33 inline ParMarkBitMap::ParMarkBitMap():
 34   _heap_start(nullptr), _heap_size(0), _beg_bits(), _virtual_space(nullptr), _reserved_byte_size(0)
 35 { }
 36 
 37 inline void ParMarkBitMap::clear_range(HeapWord* beg, HeapWord* end) {
 38   const idx_t beg_bit = addr_to_bit(beg);
 39   const idx_t end_bit = addr_to_bit(end);
 40   _beg_bits.clear_range(beg_bit, end_bit);
 41 }
 42 
 43 inline HeapWord* ParMarkBitMap::heap_start() const {
 44   return _heap_start;
 45 }
 46 
 47 inline HeapWord* ParMarkBitMap::heap_end() const {
 48   return heap_start() + heap_size();
 49 }
 50 
 51 inline size_t ParMarkBitMap::heap_size() const {
 52   return _heap_size;
 53 }
 54 
 55 inline size_t ParMarkBitMap::size() const {
 56   return _beg_bits.size();
 57 }
 58 
 59 inline bool ParMarkBitMap::is_marked(HeapWord* addr) const {
 60   return _beg_bits.at(addr_to_bit(addr));
 61 }
 62 
 63 inline bool ParMarkBitMap::is_marked(oop obj) const {
 64   return is_marked(cast_from_oop<HeapWord*>(obj));
 65 }
 66 
 67 inline bool ParMarkBitMap::is_unmarked(HeapWord* addr) const {
 68   return !is_marked(addr);
 69 }
 70 
 71 inline bool ParMarkBitMap::is_unmarked(oop obj) const {
 72   return !is_marked(obj);
 73 }
 74 
 75 inline size_t ParMarkBitMap::bits_to_words(idx_t bits) {
 76   return bits << obj_granularity_shift();
 77 }
 78 
 79 inline ParMarkBitMap::idx_t ParMarkBitMap::words_to_bits(size_t words) {
 80   return words >> obj_granularity_shift();
 81 }
 82 
 83 inline bool ParMarkBitMap::mark_obj(HeapWord* addr) {
 84   return _beg_bits.par_set_bit(addr_to_bit(addr));
 85 }
 86 
 87 inline bool ParMarkBitMap::mark_obj(oop obj) {
 88   return mark_obj(cast_from_oop<HeapWord*>(obj));
 89 }
 90 
 91 inline ParMarkBitMap::idx_t ParMarkBitMap::addr_to_bit(HeapWord* addr) const {
 92   DEBUG_ONLY(verify_addr(addr);)
 93   return words_to_bits(pointer_delta(addr, heap_start()));
 94 }
 95 
 96 inline HeapWord* ParMarkBitMap::bit_to_addr(idx_t bit) const {
 97   DEBUG_ONLY(verify_bit(bit);)
 98   return heap_start() + bits_to_words(bit);
 99 }
100 
101 inline ParMarkBitMap::idx_t ParMarkBitMap::align_range_end(idx_t range_end) const {
102   // size is aligned, so if range_end <= size then so is aligned result.
103   assert(range_end <= size(), "range end out of range");
104   return align_up(range_end, BitsPerWord);
105 }
106 
107 inline HeapWord* ParMarkBitMap::find_obj_beg(HeapWord* beg, HeapWord* end) const {
108   const idx_t beg_bit = addr_to_bit(beg);
109   const idx_t end_bit = addr_to_bit(end);
110   const idx_t search_end = align_range_end(end_bit);
111   const idx_t res_bit = MIN2(_beg_bits.find_first_set_bit_aligned_right(beg_bit, search_end),
112                              end_bit);
113   return bit_to_addr(res_bit);
114 }
115 
116 inline HeapWord* ParMarkBitMap::find_obj_beg_reverse(HeapWord* beg, HeapWord* end) const {
117   const idx_t beg_bit = addr_to_bit(beg);
118   const idx_t end_bit = addr_to_bit(end);
119   const idx_t res_bit = _beg_bits.find_last_set_bit(beg_bit, end_bit);
120   return bit_to_addr(res_bit);
121 }
122 
123 #ifdef  ASSERT
124 inline void ParMarkBitMap::verify_bit(idx_t bit) const {
125   // Allow one past the last valid bit; useful for loop bounds.
126   assert(bit <= _beg_bits.size(), "bit out of range");
127 }
128 
129 inline void ParMarkBitMap::verify_addr(HeapWord* addr) const {
130   // Allow one past the last valid address; useful for loop bounds.
131   assert(addr >= heap_start(),
132          "addr too small, addr: " PTR_FORMAT " heap start: " PTR_FORMAT, p2i(addr), p2i(heap_start()));
133   assert(addr <= heap_end(),
134          "addr too big, addr: " PTR_FORMAT " heap end: " PTR_FORMAT, p2i(addr), p2i(heap_end()));
135 }
136 #endif  // #ifdef ASSERT
137 
138 #endif // SHARE_GC_PARALLEL_PARMARKBITMAP_INLINE_HPP