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_G1_G1CONCURRENTMARK_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
27
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/g1ConcurrentMark.hpp"
30 #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
31 #include "gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
32 #include "gc/g1/suspendibleThreadSet.hpp"
33 #include "gc/shared/taskqueue.inline.hpp"
34 #include "utilities/bitMap.inline.hpp"
35
36 inline bool G1ConcurrentMark::par_mark(oop obj) {
37 return _nextMarkBitMap->par_mark((HeapWord*)obj);
38 }
39
40 #ifndef PRODUCT
41 template<typename Fn>
42 inline void G1CMMarkStack::iterate(Fn fn) const {
43 assert_at_safepoint(true);
44
45 size_t num_chunks = 0;
46
47 TaskQueueEntryChunk* cur = _chunk_list;
48 while (cur != NULL) {
49 guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
50
51 for (size_t i = 0; i < EntriesPerChunk; ++i) {
52 if (cur->data[i].is_null()) {
53 break;
54 }
55 fn(cur->data[i]);
56 }
57 cur = cur->next;
123 if (task_entry.is_array_slice()) {
124 _words_scanned += _objArray_processor.process_slice(task_entry.slice());
125 } else {
126 oop obj = task_entry.obj();
127 if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
128 _words_scanned += _objArray_processor.process_obj(obj);
129 } else {
130 _words_scanned += obj->oop_iterate_size(_cm_oop_closure);;
131 }
132 }
133 }
134 check_limits();
135 }
136
137 inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
138 obj->oop_iterate(_cm_oop_closure, mr);
139 return mr.word_size();
140 }
141
142 inline void G1CMTask::make_reference_grey(oop obj) {
143 if (_cm->par_mark(obj)) {
144 // No OrderAccess:store_load() is needed. It is implicit in the
145 // CAS done in G1CMBitMap::parMark() call in the routine above.
146 HeapWord* global_finger = _cm->finger();
147
148 // We only need to push a newly grey object on the mark
149 // stack if it is in a section of memory the mark bitmap
150 // scan has already examined. Mark bitmap scanning
151 // maintains progress "fingers" for determining that.
152 //
153 // Notice that the global finger might be moving forward
154 // concurrently. This is not a problem. In the worst case, we
155 // mark the object while it is above the global finger and, by
156 // the time we read the global finger, it has moved forward
157 // past this object. In this case, the object will probably
158 // be visited when a task is scanning the region and will also
159 // be pushed on the stack. So, some duplicate work, but no
160 // correctness problems.
161 if (is_below_finger(obj, global_finger)) {
162 G1TaskQueueEntry entry = G1TaskQueueEntry::from_oop(obj);
163 if (obj->is_typeArray()) {
164 // Immediately process arrays of primitive types, rather
165 // than pushing on the mark stack. This keeps us from
166 // adding humongous objects to the mark stack that might
167 // be reclaimed before the entry is processed - see
168 // selection of candidates for eager reclaim of humongous
169 // objects. The cost of the additional type test is
170 // mitigated by avoiding a trip through the mark stack,
171 // by only doing a bookkeeping update and avoiding the
172 // actual scan of the object - a typeArray contains no
173 // references, and the metadata is built-in.
174 process_grey_task_entry<false>(entry);
175 } else {
176 push(entry);
177 }
178 }
179 }
180 }
181
182 inline void G1CMTask::deal_with_reference(oop obj) {
183 increment_refs_reached();
184
185 HeapWord* objAddr = (HeapWord*) obj;
186 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
187 if (_g1h->is_in_g1_reserved(objAddr)) {
188 assert(obj != NULL, "null check is implicit");
189 if (!_nextMarkBitMap->is_marked(objAddr)) {
190 // Only get the containing region if the object is not marked on the
191 // bitmap (otherwise, it's a waste of time since we won't do
192 // anything with it).
193 HeapRegion* hr = _g1h->heap_region_containing(obj);
194 if (!hr->obj_allocated_since_next_marking(obj)) {
195 make_reference_grey(obj);
196 }
197 }
198 }
199 }
200
201 inline void G1ConcurrentMark::markPrev(oop p) {
202 assert(!_prevMarkBitMap->is_marked((HeapWord*) p), "sanity");
203 _prevMarkBitMap->mark((HeapWord*) p);
204 }
205
206 bool G1ConcurrentMark::isPrevMarked(oop p) const {
207 assert(p != NULL && p->is_oop(), "expected an oop");
208 return _prevMarkBitMap->is_marked((HeapWord*)p);
209 }
210
211 inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) {
212 assert(obj != NULL, "pre-condition");
213 HeapWord* addr = (HeapWord*) obj;
214 if (hr == NULL) {
215 hr = _g1h->heap_region_containing(addr);
216 } else {
217 assert(hr->is_in(addr), "pre-condition");
218 }
219 assert(hr != NULL, "sanity");
220 // Given that we're looking for a region that contains an object
221 // header it's impossible to get back a HC region.
222 assert(!hr->is_continues_humongous(), "sanity");
223
224 if (addr < hr->next_top_at_mark_start()) {
225 if (!_nextMarkBitMap->is_marked(addr)) {
226 par_mark(obj);
227 }
228 }
229 }
230
231 inline bool G1ConcurrentMark::do_yield_check() {
232 if (SuspendibleThreadSet::should_yield()) {
233 SuspendibleThreadSet::yield();
234 return true;
235 } else {
236 return false;
237 }
238 }
239
240 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
|
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_G1_G1CONCURRENTMARK_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
27
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/g1ConcurrentMark.hpp"
30 #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
31 #include "gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
32 #include "gc/g1/suspendibleThreadSet.hpp"
33 #include "gc/shared/taskqueue.inline.hpp"
34 #include "utilities/bitMap.inline.hpp"
35
36 inline bool G1ConcurrentMark::mark_in_next_bitmap(oop const obj) {
37 HeapRegion* const hr = _g1h->heap_region_containing(obj);
38 return mark_in_next_bitmap(hr, obj);
39 }
40
41 inline bool G1ConcurrentMark::mark_in_next_bitmap(HeapRegion* const hr, oop const obj) {
42 assert(hr != NULL, "just checking");
43 assert(hr->is_in_reserved(obj),
44 "Attempting to mark object at " PTR_FORMAT " that is not contained in the given region %u",
45 p2i(obj), hr->hrm_index());
46
47 if (hr->obj_allocated_since_next_marking(obj)) {
48 return false;
49 }
50
51 // Some callers may have stale objects to mark above nTAMS after humongous reclaim.
52 assert(obj->is_oop(true /* ignore mark word */), "Address " PTR_FORMAT " to mark is not an oop", p2i(obj));
53 assert(!hr->is_continues_humongous(),
54 "Should not try to mark object " PTR_FORMAT " in Humongous continues region %u above nTAMS " PTR_FORMAT,
55 p2i(obj), hr->hrm_index(), p2i(hr->next_top_at_mark_start()));
56
57 HeapWord* const obj_addr = (HeapWord*)obj;
58 return _nextMarkBitMap->par_mark(obj_addr);
59 }
60
61 #ifndef PRODUCT
62 template<typename Fn>
63 inline void G1CMMarkStack::iterate(Fn fn) const {
64 assert_at_safepoint(true);
65
66 size_t num_chunks = 0;
67
68 TaskQueueEntryChunk* cur = _chunk_list;
69 while (cur != NULL) {
70 guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
71
72 for (size_t i = 0; i < EntriesPerChunk; ++i) {
73 if (cur->data[i].is_null()) {
74 break;
75 }
76 fn(cur->data[i]);
77 }
78 cur = cur->next;
144 if (task_entry.is_array_slice()) {
145 _words_scanned += _objArray_processor.process_slice(task_entry.slice());
146 } else {
147 oop obj = task_entry.obj();
148 if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
149 _words_scanned += _objArray_processor.process_obj(obj);
150 } else {
151 _words_scanned += obj->oop_iterate_size(_cm_oop_closure);;
152 }
153 }
154 }
155 check_limits();
156 }
157
158 inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
159 obj->oop_iterate(_cm_oop_closure, mr);
160 return mr.word_size();
161 }
162
163 inline void G1CMTask::make_reference_grey(oop obj) {
164 if (!_cm->mark_in_next_bitmap(obj)) {
165 return;
166 }
167
168 // No OrderAccess:store_load() is needed. It is implicit in the
169 // CAS done in G1CMBitMap::parMark() call in the routine above.
170 HeapWord* global_finger = _cm->finger();
171
172 // We only need to push a newly grey object on the mark
173 // stack if it is in a section of memory the mark bitmap
174 // scan has already examined. Mark bitmap scanning
175 // maintains progress "fingers" for determining that.
176 //
177 // Notice that the global finger might be moving forward
178 // concurrently. This is not a problem. In the worst case, we
179 // mark the object while it is above the global finger and, by
180 // the time we read the global finger, it has moved forward
181 // past this object. In this case, the object will probably
182 // be visited when a task is scanning the region and will also
183 // be pushed on the stack. So, some duplicate work, but no
184 // correctness problems.
185 if (is_below_finger(obj, global_finger)) {
186 G1TaskQueueEntry entry = G1TaskQueueEntry::from_oop(obj);
187 if (obj->is_typeArray()) {
188 // Immediately process arrays of primitive types, rather
189 // than pushing on the mark stack. This keeps us from
190 // adding humongous objects to the mark stack that might
191 // be reclaimed before the entry is processed - see
192 // selection of candidates for eager reclaim of humongous
193 // objects. The cost of the additional type test is
194 // mitigated by avoiding a trip through the mark stack,
195 // by only doing a bookkeeping update and avoiding the
196 // actual scan of the object - a typeArray contains no
197 // references, and the metadata is built-in.
198 process_grey_task_entry<false>(entry);
199 } else {
200 push(entry);
201 }
202 }
203 }
204
205 inline void G1CMTask::deal_with_reference(oop obj) {
206 increment_refs_reached();
207
208 HeapWord* objAddr = (HeapWord*) obj;
209 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
210 if (_g1h->is_in_g1_reserved(objAddr)) {
211 assert(obj != NULL, "null check is implicit");
212 if (!_nextMarkBitMap->is_marked(objAddr)) {
213 // Only get the containing region if the object is not marked on the
214 // bitmap (otherwise, it's a waste of time since we won't do
215 // anything with it).
216 HeapRegion* hr = _g1h->heap_region_containing(obj);
217 if (!hr->obj_allocated_since_next_marking(obj)) {
218 make_reference_grey(obj);
219 }
220 }
221 }
222 }
223
224 inline void G1ConcurrentMark::markPrev(oop p) {
225 assert(!_prevMarkBitMap->is_marked((HeapWord*) p), "sanity");
226 _prevMarkBitMap->mark((HeapWord*) p);
227 }
228
229 bool G1ConcurrentMark::isPrevMarked(oop p) const {
230 assert(p != NULL && p->is_oop(), "expected an oop");
231 return _prevMarkBitMap->is_marked((HeapWord*)p);
232 }
233
234 inline bool G1ConcurrentMark::do_yield_check() {
235 if (SuspendibleThreadSet::should_yield()) {
236 SuspendibleThreadSet::yield();
237 return true;
238 } else {
239 return false;
240 }
241 }
242
243 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
|