1 /*
2 * Copyright (c) 2001, 2016, 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 *
80
81 inline void G1CMBitMap::clear(HeapWord* addr) {
82 check_mark(addr);
83 _bm.clear_bit(heapWordToOffset(addr));
84 }
85
86 inline bool G1CMBitMap::parMark(HeapWord* addr) {
87 check_mark(addr);
88 return _bm.par_set_bit(heapWordToOffset(addr));
89 }
90
91 #undef check_mark
92
93 #ifndef PRODUCT
94 template<typename Fn>
95 inline void G1CMMarkStack::iterate(Fn fn) const {
96 assert_at_safepoint(true);
97
98 size_t num_chunks = 0;
99
100 OopChunk* cur = _chunk_list;
101 while (cur != NULL) {
102 guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
103
104 for (size_t i = 0; i < OopsPerChunk; ++i) {
105 if (cur->data[i] == NULL) {
106 break;
107 }
108 fn(cur->data[i]);
109 }
110 cur = cur->next;
111 num_chunks++;
112 }
113 }
114 #endif
115
116 // It scans an object and visits its children.
117 inline void G1CMTask::scan_object(oop obj) { process_grey_object<true>(obj); }
118
119 inline void G1CMTask::push(oop obj) {
120 HeapWord* objAddr = (HeapWord*) obj;
121 assert(G1CMObjArrayProcessor::is_array_slice(obj) || _g1h->is_in_g1_reserved(objAddr), "invariant");
122 assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_on_master_free_list(
123 _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
124 assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_obj_ill(obj), "invariant");
125 assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked(objAddr), "invariant");
126
127 if (!_task_queue->push(obj)) {
128 // The local task queue looks full. We need to push some entries
129 // to the global stack.
130 move_entries_to_global_stack();
131
132 // this should succeed since, even if we overflow the global
133 // stack, we should have definitely removed some entries from the
134 // local queue. So, there must be space on it.
135 bool success = _task_queue->push(obj);
136 assert(success, "invariant");
137 }
138 }
139
140 inline bool G1CMTask::is_below_finger(oop obj, HeapWord* global_finger) const {
141 // If obj is above the global finger, then the mark bitmap scan
142 // will find it later, and no push is needed. Similarly, if we have
143 // a current region and obj is between the local finger and the
144 // end of the current region, then no push is needed. The tradeoff
145 // of checking both vs only checking the global finger is that the
146 // local check will be more accurate and so result in fewer pushes,
147 // but may also be a little slower.
148 HeapWord* objAddr = (HeapWord*)obj;
149 if (_finger != NULL) {
150 // We have a current region.
151
152 // Finger and region values are all NULL or all non-NULL. We
153 // use _finger to check since we immediately use its value.
154 assert(_curr_region != NULL, "invariant");
155 assert(_region_limit != NULL, "invariant");
156 assert(_region_limit <= global_finger, "invariant");
157
158 // True if obj is less than the local finger, or is between
159 // the region limit and the global finger.
160 if (objAddr < _finger) {
161 return true;
162 } else if (objAddr < _region_limit) {
163 return false;
164 } // Else check global finger.
165 }
166 // Check global finger.
167 return objAddr < global_finger;
168 }
169
170 template<bool scan>
171 inline void G1CMTask::process_grey_object(oop obj) {
172 assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
173 assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked((HeapWord*) obj),
174 "Any stolen object should be a slice or marked");
175
176 if (scan) {
177 if (G1CMObjArrayProcessor::is_array_slice(obj)) {
178 _words_scanned += _objArray_processor.process_slice(obj);
179 } else if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
180 _words_scanned += _objArray_processor.process_obj(obj);
181 } else {
182 _words_scanned += obj->oop_iterate_size(_cm_oop_closure);;
183 }
184 }
185 check_limits();
186 }
187
188 inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
189 obj->oop_iterate(_cm_oop_closure, mr);
190 return mr.word_size();
191 }
192
193 inline void G1CMTask::make_reference_grey(oop obj) {
194 if (_cm->par_mark(obj)) {
195 // No OrderAccess:store_load() is needed. It is implicit in the
196 // CAS done in G1CMBitMap::parMark() call in the routine above.
197 HeapWord* global_finger = _cm->finger();
198
199 // We only need to push a newly grey object on the mark
200 // stack if it is in a section of memory the mark bitmap
201 // scan has already examined. Mark bitmap scanning
202 // maintains progress "fingers" for determining that.
203 //
204 // Notice that the global finger might be moving forward
205 // concurrently. This is not a problem. In the worst case, we
206 // mark the object while it is above the global finger and, by
207 // the time we read the global finger, it has moved forward
208 // past this object. In this case, the object will probably
209 // be visited when a task is scanning the region and will also
210 // be pushed on the stack. So, some duplicate work, but no
211 // correctness problems.
212 if (is_below_finger(obj, global_finger)) {
213 if (obj->is_typeArray()) {
214 // Immediately process arrays of primitive types, rather
215 // than pushing on the mark stack. This keeps us from
216 // adding humongous objects to the mark stack that might
217 // be reclaimed before the entry is processed - see
218 // selection of candidates for eager reclaim of humongous
219 // objects. The cost of the additional type test is
220 // mitigated by avoiding a trip through the mark stack,
221 // by only doing a bookkeeping update and avoiding the
222 // actual scan of the object - a typeArray contains no
223 // references, and the metadata is built-in.
224 process_grey_object<false>(obj);
225 } else {
226 push(obj);
227 }
228 }
229 }
230 }
231
232 inline void G1CMTask::deal_with_reference(oop obj) {
233 increment_refs_reached();
234
235 HeapWord* objAddr = (HeapWord*) obj;
236 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
237 if (_g1h->is_in_g1_reserved(objAddr)) {
238 assert(obj != NULL, "null check is implicit");
239 if (!_nextMarkBitMap->isMarked(objAddr)) {
240 // Only get the containing region if the object is not marked on the
241 // bitmap (otherwise, it's a waste of time since we won't do
242 // anything with it).
243 HeapRegion* hr = _g1h->heap_region_containing(obj);
244 if (!hr->obj_allocated_since_next_marking(obj)) {
245 make_reference_grey(obj);
246 }
|
1 /*
2 * Copyright (c) 2001, 2017, 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 *
80
81 inline void G1CMBitMap::clear(HeapWord* addr) {
82 check_mark(addr);
83 _bm.clear_bit(heapWordToOffset(addr));
84 }
85
86 inline bool G1CMBitMap::parMark(HeapWord* addr) {
87 check_mark(addr);
88 return _bm.par_set_bit(heapWordToOffset(addr));
89 }
90
91 #undef check_mark
92
93 #ifndef PRODUCT
94 template<typename Fn>
95 inline void G1CMMarkStack::iterate(Fn fn) const {
96 assert_at_safepoint(true);
97
98 size_t num_chunks = 0;
99
100 TaskQueueEntryChunk* cur = _chunk_list;
101 while (cur != NULL) {
102 guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
103
104 for (size_t i = 0; i < EntriesPerChunk; ++i) {
105 if (cur->data[i].is_null()) {
106 break;
107 }
108 fn(cur->data[i]);
109 }
110 cur = cur->next;
111 num_chunks++;
112 }
113 }
114 #endif
115
116 // It scans an object and visits its children.
117 inline void G1CMTask::scan_task_entry(G1TaskQueueEntry task_entry) { process_grey_task_entry<true>(task_entry); }
118
119 inline void G1CMTask::push(G1TaskQueueEntry task_entry) {
120 assert(task_entry.is_array_slice() || _g1h->is_in_g1_reserved(task_entry.obj()), "invariant");
121 assert(task_entry.is_array_slice() || !_g1h->is_on_master_free_list(
122 _g1h->heap_region_containing(task_entry.obj())), "invariant");
123 assert(task_entry.is_array_slice() || !_g1h->is_obj_ill(task_entry.obj()), "invariant"); // FIXME!!!
124 assert(task_entry.is_array_slice() || _nextMarkBitMap->isMarked((HeapWord*)task_entry.obj()), "invariant");
125
126 if (!_task_queue->push(task_entry)) {
127 // The local task queue looks full. We need to push some entries
128 // to the global stack.
129 move_entries_to_global_stack();
130
131 // this should succeed since, even if we overflow the global
132 // stack, we should have definitely removed some entries from the
133 // local queue. So, there must be space on it.
134 bool success = _task_queue->push(task_entry);
135 assert(success, "invariant");
136 }
137 }
138
139 inline bool G1CMTask::is_below_finger(oop obj, HeapWord* global_finger) const {
140 // If obj is above the global finger, then the mark bitmap scan
141 // will find it later, and no push is needed. Similarly, if we have
142 // a current region and obj is between the local finger and the
143 // end of the current region, then no push is needed. The tradeoff
144 // of checking both vs only checking the global finger is that the
145 // local check will be more accurate and so result in fewer pushes,
146 // but may also be a little slower.
147 HeapWord* objAddr = (HeapWord*)obj;
148 if (_finger != NULL) {
149 // We have a current region.
150
151 // Finger and region values are all NULL or all non-NULL. We
152 // use _finger to check since we immediately use its value.
153 assert(_curr_region != NULL, "invariant");
154 assert(_region_limit != NULL, "invariant");
155 assert(_region_limit <= global_finger, "invariant");
156
157 // True if obj is less than the local finger, or is between
158 // the region limit and the global finger.
159 if (objAddr < _finger) {
160 return true;
161 } else if (objAddr < _region_limit) {
162 return false;
163 } // Else check global finger.
164 }
165 // Check global finger.
166 return objAddr < global_finger;
167 }
168
169 template<bool scan>
170 inline void G1CMTask::process_grey_task_entry(G1TaskQueueEntry task_entry) {
171 assert(scan || (task_entry.is_oop() && task_entry.obj()->is_typeArray()), "Skipping scan of grey non-typeArray");
172 assert(task_entry.is_array_slice() || _nextMarkBitMap->isMarked((HeapWord*)task_entry.obj()),
173 "Any stolen object should be a slice or marked");
174
175 if (scan) {
176 if (task_entry.is_array_slice()) {
177 _words_scanned += _objArray_processor.process_slice(task_entry.slice());
178 } else {
179 oop obj = task_entry.obj();
180 if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
181 _words_scanned += _objArray_processor.process_obj(obj);
182 } else {
183 _words_scanned += obj->oop_iterate_size(_cm_oop_closure);;
184 }
185 }
186 }
187 check_limits();
188 }
189
190 inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
191 obj->oop_iterate(_cm_oop_closure, mr);
192 return mr.word_size();
193 }
194
195 inline void G1CMTask::make_reference_grey(oop obj) {
196 if (_cm->par_mark(obj)) {
197 // No OrderAccess:store_load() is needed. It is implicit in the
198 // CAS done in G1CMBitMap::parMark() call in the routine above.
199 HeapWord* global_finger = _cm->finger();
200
201 // We only need to push a newly grey object on the mark
202 // stack if it is in a section of memory the mark bitmap
203 // scan has already examined. Mark bitmap scanning
204 // maintains progress "fingers" for determining that.
205 //
206 // Notice that the global finger might be moving forward
207 // concurrently. This is not a problem. In the worst case, we
208 // mark the object while it is above the global finger and, by
209 // the time we read the global finger, it has moved forward
210 // past this object. In this case, the object will probably
211 // be visited when a task is scanning the region and will also
212 // be pushed on the stack. So, some duplicate work, but no
213 // correctness problems.
214 if (is_below_finger(obj, global_finger)) {
215 G1TaskQueueEntry entry = G1TaskQueueEntry::from_oop(obj);
216 if (obj->is_typeArray()) {
217 // Immediately process arrays of primitive types, rather
218 // than pushing on the mark stack. This keeps us from
219 // adding humongous objects to the mark stack that might
220 // be reclaimed before the entry is processed - see
221 // selection of candidates for eager reclaim of humongous
222 // objects. The cost of the additional type test is
223 // mitigated by avoiding a trip through the mark stack,
224 // by only doing a bookkeeping update and avoiding the
225 // actual scan of the object - a typeArray contains no
226 // references, and the metadata is built-in.
227 process_grey_task_entry<false>(entry);
228 } else {
229 push(entry);
230 }
231 }
232 }
233 }
234
235 inline void G1CMTask::deal_with_reference(oop obj) {
236 increment_refs_reached();
237
238 HeapWord* objAddr = (HeapWord*) obj;
239 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
240 if (_g1h->is_in_g1_reserved(objAddr)) {
241 assert(obj != NULL, "null check is implicit");
242 if (!_nextMarkBitMap->isMarked(objAddr)) {
243 // Only get the containing region if the object is not marked on the
244 // bitmap (otherwise, it's a waste of time since we won't do
245 // anything with it).
246 HeapRegion* hr = _g1h->heap_region_containing(obj);
247 if (!hr->obj_allocated_since_next_marking(obj)) {
248 make_reference_grey(obj);
249 }
|