Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp @ 20504:6948da6d7c13
8052172: Evacuation failure handling in G1 does not evacuate all objects if -XX:-G1DeferredRSUpdate is set
Summary: Remove -XX:-G1DeferredRSUpdate functionality as it is racy. During evacuation failure handling, threads where evacuation failure handling occurred may try to add remembered sets to regions which remembered sets are currently being scanned. The iterator to handle the remembered set scan does not support addition of entries during scan and so may skip valid references.
Reviewed-by: iveresov, brutisso, mgerdin
author | tschatzl |
---|---|
date | Tue, 30 Sep 2014 09:44:36 +0200 |
parents | 1f1d373cd044 |
children | 0fcaab91d485 |
rev | line source |
---|---|
342 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
7181
diff
changeset
|
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
845
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
845
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
845
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP | |
27 | |
28 #include "gc_implementation/g1/g1BlockOffsetTable.hpp" | |
20276
1526a938e670
8047818: G1 HeapRegions can no longer be ContiguousSpaces
mgerdin
parents:
20273
diff
changeset
|
29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
1526a938e670
8047818: G1 HeapRegions can no longer be ContiguousSpaces
mgerdin
parents:
20273
diff
changeset
|
30 #include "gc_implementation/g1/heapRegion.inline.hpp" |
1972 | 31 #include "memory/space.hpp" |
32 | |
342 | 33 inline HeapWord* G1BlockOffsetTable::block_start(const void* addr) { |
34 if (addr >= _bottom && addr < _end) { | |
35 return block_start_unsafe(addr); | |
36 } else { | |
37 return NULL; | |
38 } | |
39 } | |
40 | |
41 inline HeapWord* | |
42 G1BlockOffsetTable::block_start_const(const void* addr) const { | |
43 if (addr >= _bottom && addr < _end) { | |
44 return block_start_unsafe_const(addr); | |
45 } else { | |
46 return NULL; | |
47 } | |
48 } | |
49 | |
20337 | 50 #define check_index(index, msg) \ |
51 assert((index) < (_reserved.word_size() >> LogN_words), \ | |
52 err_msg("%s - index: "SIZE_FORMAT", _vs.committed_size: "SIZE_FORMAT, \ | |
53 msg, (index), (_reserved.word_size() >> LogN_words))); \ | |
54 assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)), \ | |
55 err_msg("Index "SIZE_FORMAT" corresponding to "PTR_FORMAT \ | |
56 " (%u) is not in committed area.", \ | |
57 (index), \ | |
58 p2i(address_for_index_raw(index)), \ | |
59 G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index)))); | |
60 | |
61 u_char G1BlockOffsetSharedArray::offset_array(size_t index) const { | |
62 check_index(index, "index out of range"); | |
63 return _offset_array[index]; | |
64 } | |
65 | |
66 void G1BlockOffsetSharedArray::set_offset_array(size_t index, u_char offset) { | |
67 check_index(index, "index out of range"); | |
68 set_offset_array_raw(index, offset); | |
69 } | |
70 | |
71 void G1BlockOffsetSharedArray::set_offset_array(size_t index, HeapWord* high, HeapWord* low) { | |
72 check_index(index, "index out of range"); | |
73 assert(high >= low, "addresses out of order"); | |
74 size_t offset = pointer_delta(high, low); | |
75 check_offset(offset, "offset too large"); | |
76 set_offset_array(index, (u_char)offset); | |
77 } | |
78 | |
79 void G1BlockOffsetSharedArray::set_offset_array(size_t left, size_t right, u_char offset) { | |
80 check_index(right, "right index out of range"); | |
81 assert(left <= right, "indexes out of order"); | |
82 size_t num_cards = right - left + 1; | |
83 if (UseMemSetInBOT) { | |
84 memset(&_offset_array[left], offset, num_cards); | |
85 } else { | |
86 size_t i = left; | |
87 const size_t end = i + num_cards; | |
88 for (; i < end; i++) { | |
89 _offset_array[i] = offset; | |
90 } | |
91 } | |
92 } | |
93 | |
94 void G1BlockOffsetSharedArray::check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { | |
95 check_index(index, "index out of range"); | |
96 assert(high >= low, "addresses out of order"); | |
97 check_offset(pointer_delta(high, low), "offset too large"); | |
98 assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); | |
99 } | |
100 | |
101 // Variant of index_for that does not check the index for validity. | |
102 inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const { | |
103 return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN; | |
104 } | |
105 | |
342 | 106 inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { |
107 char* pc = (char*)p; | |
108 assert(pc >= (char*)_reserved.start() && | |
109 pc < (char*)_reserved.end(), | |
7181
2fc0334f613a
7194633: G1: Assertion and guarantee failures in block offset table
johnc
parents:
6725
diff
changeset
|
110 err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")", |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
7181
diff
changeset
|
111 p2i(p), p2i(_reserved.start()), p2i(_reserved.end()))); |
20337 | 112 size_t result = index_for_raw(p); |
7181
2fc0334f613a
7194633: G1: Assertion and guarantee failures in block offset table
johnc
parents:
6725
diff
changeset
|
113 check_index(result, "bad index from address"); |
342 | 114 return result; |
115 } | |
116 | |
117 inline HeapWord* | |
118 G1BlockOffsetSharedArray::address_for_index(size_t index) const { | |
7181
2fc0334f613a
7194633: G1: Assertion and guarantee failures in block offset table
johnc
parents:
6725
diff
changeset
|
119 check_index(index, "index out of range"); |
20337 | 120 HeapWord* result = address_for_index_raw(index); |
342 | 121 assert(result >= _reserved.start() && result < _reserved.end(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
122 err_msg("bad address from index result " PTR_FORMAT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
123 " _reserved.start() " PTR_FORMAT " _reserved.end() " |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
124 PTR_FORMAT, |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
7181
diff
changeset
|
125 p2i(result), p2i(_reserved.start()), p2i(_reserved.end()))); |
342 | 126 return result; |
127 } | |
128 | |
20337 | 129 #undef check_index |
130 | |
20273
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
131 inline size_t |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
132 G1BlockOffsetArray::block_size(const HeapWord* p) const { |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
133 return gsp()->block_size(p); |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
134 } |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
135 |
342 | 136 inline HeapWord* |
137 G1BlockOffsetArray::block_at_or_preceding(const void* addr, | |
138 bool has_max_index, | |
139 size_t max_index) const { | |
140 assert(_array->offset_array(0) == 0, "objects can't cross covered areas"); | |
141 size_t index = _array->index_for(addr); | |
142 // We must make sure that the offset table entry we use is valid. If | |
143 // "addr" is past the end, start at the last known one and go forward. | |
144 if (has_max_index) { | |
145 index = MIN2(index, max_index); | |
146 } | |
147 HeapWord* q = _array->address_for_index(index); | |
148 | |
149 uint offset = _array->offset_array(index); // Extend u_char to uint. | |
150 while (offset >= N_words) { | |
151 // The excess of the offset from N_words indicates a power of Base | |
152 // to go back by. | |
153 size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset); | |
154 q -= (N_words * n_cards_back); | |
20273
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
155 assert(q >= gsp()->bottom(), "Went below bottom!"); |
342 | 156 index -= n_cards_back; |
157 offset = _array->offset_array(index); | |
158 } | |
159 assert(offset < N_words, "offset too large"); | |
160 q -= offset; | |
161 return q; | |
162 } | |
163 | |
164 inline HeapWord* | |
165 G1BlockOffsetArray:: | |
166 forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n, | |
167 const void* addr) const { | |
20273
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
168 if (addr >= gsp()->top()) return gsp()->top(); |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
169 while (n <= addr) { |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
170 q = n; |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
171 oop obj = oop(q); |
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
172 if (obj->klass_or_null() == NULL) return q; |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20276
diff
changeset
|
173 n += block_size(q); |
342 | 174 } |
175 assert(q <= n, "wrong order for q and addr"); | |
176 assert(addr < n, "wrong order for addr and n"); | |
177 return q; | |
178 } | |
179 | |
180 inline HeapWord* | |
181 G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, | |
182 const void* addr) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
342
diff
changeset
|
183 if (oop(q)->klass_or_null() == NULL) return q; |
20273
9441d22e429a
8047820: G1 Block offset table does not need to support generic Space classes
mgerdin
parents:
17937
diff
changeset
|
184 HeapWord* n = q + block_size(q); |
342 | 185 // In the normal case, where the query "addr" is a card boundary, and the |
186 // offset table chunks are the same size as cards, the block starting at | |
187 // "q" will contain addr, so the test below will fail, and we'll fall | |
188 // through quickly. | |
189 if (n <= addr) { | |
190 q = forward_to_block_containing_addr_slow(q, n, addr); | |
191 } | |
192 assert(q <= addr, "wrong order for current and arg"); | |
193 return q; | |
194 } | |
195 | |
196 ////////////////////////////////////////////////////////////////////////// | |
197 // BlockOffsetArrayNonContigSpace inlines | |
198 ////////////////////////////////////////////////////////////////////////// | |
199 inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) { | |
200 // Verify that the BOT shows [blk_start, blk_end) to be one block. | |
201 verify_single_block(blk_start, blk_end); | |
202 // adjust _unallocated_block upward or downward | |
203 // as appropriate | |
204 if (BlockOffsetArrayUseUnallocatedBlock) { | |
205 assert(_unallocated_block <= _end, | |
206 "Inconsistent value for _unallocated_block"); | |
207 if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) { | |
208 // CMS-specific note: a block abutting _unallocated_block to | |
209 // its left is being freed, a new block is being added or | |
210 // we are resetting following a compaction | |
211 _unallocated_block = blk_start; | |
212 } | |
213 } | |
214 } | |
215 | |
216 inline void G1BlockOffsetArray::freed(HeapWord* blk, size_t size) { | |
217 freed(blk, blk + size); | |
218 } | |
1972 | 219 |
220 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP |