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_aligned_left(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