|
1 /* |
|
2 * Copyright (c) 1997, 2015, 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 #include "precompiled.hpp" |
|
26 #include "compiler/compileBroker.hpp" |
|
27 #include "gc/serial/markSweep.inline.hpp" |
|
28 #include "gc/shared/collectedHeap.inline.hpp" |
|
29 #include "gc/shared/gcTimer.hpp" |
|
30 #include "gc/shared/gcTrace.hpp" |
|
31 #include "oops/instanceKlass.inline.hpp" |
|
32 #include "oops/instanceMirrorKlass.inline.hpp" |
|
33 #include "oops/methodData.hpp" |
|
34 #include "oops/objArrayKlass.inline.hpp" |
|
35 #include "oops/oop.inline.hpp" |
|
36 |
|
37 uint MarkSweep::_total_invocations = 0; |
|
38 |
|
39 Stack<oop, mtGC> MarkSweep::_marking_stack; |
|
40 Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack; |
|
41 |
|
42 Stack<oop, mtGC> MarkSweep::_preserved_oop_stack; |
|
43 Stack<markOop, mtGC> MarkSweep::_preserved_mark_stack; |
|
44 size_t MarkSweep::_preserved_count = 0; |
|
45 size_t MarkSweep::_preserved_count_max = 0; |
|
46 PreservedMark* MarkSweep::_preserved_marks = NULL; |
|
47 ReferenceProcessor* MarkSweep::_ref_processor = NULL; |
|
48 STWGCTimer* MarkSweep::_gc_timer = NULL; |
|
49 SerialOldTracer* MarkSweep::_gc_tracer = NULL; |
|
50 |
|
51 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; |
|
52 |
|
53 void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } |
|
54 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); } |
|
55 |
|
56 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; |
|
57 CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure); |
|
58 CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure); |
|
59 |
|
60 template <typename T> |
|
61 void MarkSweep::MarkAndPushClosure::do_oop_nv(T* p) { mark_and_push(p); } |
|
62 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { do_oop_nv(p); } |
|
63 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { do_oop_nv(p); } |
|
64 |
|
65 void MarkSweep::follow_class_loader(ClassLoaderData* cld) { |
|
66 MarkSweep::follow_cld_closure.do_cld(cld); |
|
67 } |
|
68 |
|
69 void InstanceKlass::oop_ms_follow_contents(oop obj) { |
|
70 assert(obj != NULL, "can't follow the content of NULL object"); |
|
71 MarkSweep::follow_klass(this); |
|
72 |
|
73 oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::mark_and_push_closure); |
|
74 } |
|
75 |
|
76 void InstanceMirrorKlass::oop_ms_follow_contents(oop obj) { |
|
77 InstanceKlass::oop_ms_follow_contents(obj); |
|
78 |
|
79 // Follow the klass field in the mirror |
|
80 Klass* klass = java_lang_Class::as_Klass(obj); |
|
81 if (klass != NULL) { |
|
82 // An anonymous class doesn't have its own class loader, so the call |
|
83 // to follow_klass will mark and push its java mirror instead of the |
|
84 // class loader. When handling the java mirror for an anonymous class |
|
85 // we need to make sure its class loader data is claimed, this is done |
|
86 // by calling follow_class_loader explicitly. For non-anonymous classes |
|
87 // the call to follow_class_loader is made when the class loader itself |
|
88 // is handled. |
|
89 if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { |
|
90 MarkSweep::follow_class_loader(klass->class_loader_data()); |
|
91 } else { |
|
92 MarkSweep::follow_klass(klass); |
|
93 } |
|
94 } else { |
|
95 // If klass is NULL then this a mirror for a primitive type. |
|
96 // We don't have to follow them, since they are handled as strong |
|
97 // roots in Universe::oops_do. |
|
98 assert(java_lang_Class::is_primitive(obj), "Sanity check"); |
|
99 } |
|
100 |
|
101 oop_oop_iterate_statics<true>(obj, &MarkSweep::mark_and_push_closure); |
|
102 } |
|
103 |
|
104 void InstanceClassLoaderKlass::oop_ms_follow_contents(oop obj) { |
|
105 InstanceKlass::oop_ms_follow_contents(obj); |
|
106 |
|
107 ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj); |
|
108 |
|
109 // We must NULL check here, since the class loader |
|
110 // can be found before the loader data has been set up. |
|
111 if(loader_data != NULL) { |
|
112 MarkSweep::follow_class_loader(loader_data); |
|
113 } |
|
114 } |
|
115 |
|
116 template <class T> |
|
117 static void oop_ms_follow_contents_specialized(InstanceRefKlass* klass, oop obj) { |
|
118 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
|
119 T heap_oop = oopDesc::load_heap_oop(referent_addr); |
|
120 debug_only( |
|
121 if(TraceReferenceGC && PrintGCDetails) { |
|
122 gclog_or_tty->print_cr("InstanceRefKlass::oop_ms_follow_contents_specialized " PTR_FORMAT, p2i(obj)); |
|
123 } |
|
124 ) |
|
125 if (!oopDesc::is_null(heap_oop)) { |
|
126 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); |
|
127 if (!referent->is_gc_marked() && |
|
128 MarkSweep::ref_processor()->discover_reference(obj, klass->reference_type())) { |
|
129 // reference was discovered, referent will be traversed later |
|
130 klass->InstanceKlass::oop_ms_follow_contents(obj); |
|
131 debug_only( |
|
132 if(TraceReferenceGC && PrintGCDetails) { |
|
133 gclog_or_tty->print_cr(" Non NULL enqueued " PTR_FORMAT, p2i(obj)); |
|
134 } |
|
135 ) |
|
136 return; |
|
137 } else { |
|
138 // treat referent as normal oop |
|
139 debug_only( |
|
140 if(TraceReferenceGC && PrintGCDetails) { |
|
141 gclog_or_tty->print_cr(" Non NULL normal " PTR_FORMAT, p2i(obj)); |
|
142 } |
|
143 ) |
|
144 MarkSweep::mark_and_push(referent_addr); |
|
145 } |
|
146 } |
|
147 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
|
148 // Treat discovered as normal oop, if ref is not "active", |
|
149 // i.e. if next is non-NULL. |
|
150 T next_oop = oopDesc::load_heap_oop(next_addr); |
|
151 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" |
|
152 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
153 debug_only( |
|
154 if(TraceReferenceGC && PrintGCDetails) { |
|
155 gclog_or_tty->print_cr(" Process discovered as normal " |
|
156 PTR_FORMAT, p2i(discovered_addr)); |
|
157 } |
|
158 ) |
|
159 MarkSweep::mark_and_push(discovered_addr); |
|
160 } |
|
161 // treat next as normal oop. next is a link in the reference queue. |
|
162 debug_only( |
|
163 if(TraceReferenceGC && PrintGCDetails) { |
|
164 gclog_or_tty->print_cr(" Process next as normal " PTR_FORMAT, p2i(next_addr)); |
|
165 } |
|
166 ) |
|
167 MarkSweep::mark_and_push(next_addr); |
|
168 klass->InstanceKlass::oop_ms_follow_contents(obj); |
|
169 } |
|
170 |
|
171 void InstanceRefKlass::oop_ms_follow_contents(oop obj) { |
|
172 if (UseCompressedOops) { |
|
173 oop_ms_follow_contents_specialized<narrowOop>(this, obj); |
|
174 } else { |
|
175 oop_ms_follow_contents_specialized<oop>(this, obj); |
|
176 } |
|
177 } |
|
178 |
|
179 template <class T> |
|
180 static void oop_ms_follow_contents_specialized(oop obj, int index) { |
|
181 objArrayOop a = objArrayOop(obj); |
|
182 const size_t len = size_t(a->length()); |
|
183 const size_t beg_index = size_t(index); |
|
184 assert(beg_index < len || len == 0, "index too large"); |
|
185 |
|
186 const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride); |
|
187 const size_t end_index = beg_index + stride; |
|
188 T* const base = (T*)a->base(); |
|
189 T* const beg = base + beg_index; |
|
190 T* const end = base + end_index; |
|
191 |
|
192 // Push the non-NULL elements of the next stride on the marking stack. |
|
193 for (T* e = beg; e < end; e++) { |
|
194 MarkSweep::mark_and_push<T>(e); |
|
195 } |
|
196 |
|
197 if (end_index < len) { |
|
198 MarkSweep::push_objarray(a, end_index); // Push the continuation. |
|
199 } |
|
200 } |
|
201 |
|
202 void ObjArrayKlass::oop_ms_follow_contents(oop obj) { |
|
203 assert (obj->is_array(), "obj must be array"); |
|
204 MarkSweep::follow_klass(this); |
|
205 if (UseCompressedOops) { |
|
206 oop_ms_follow_contents_specialized<narrowOop>(obj, 0); |
|
207 } else { |
|
208 oop_ms_follow_contents_specialized<oop>(obj, 0); |
|
209 } |
|
210 } |
|
211 |
|
212 void TypeArrayKlass::oop_ms_follow_contents(oop obj) { |
|
213 assert(obj->is_typeArray(),"must be a type array"); |
|
214 // Performance tweak: We skip iterating over the klass pointer since we |
|
215 // know that Universe::TypeArrayKlass never moves. |
|
216 } |
|
217 |
|
218 void MarkSweep::follow_array(objArrayOop array, int index) { |
|
219 if (UseCompressedOops) { |
|
220 oop_ms_follow_contents_specialized<narrowOop>(array, index); |
|
221 } else { |
|
222 oop_ms_follow_contents_specialized<oop>(array, index); |
|
223 } |
|
224 } |
|
225 |
|
226 void MarkSweep::follow_stack() { |
|
227 do { |
|
228 while (!_marking_stack.is_empty()) { |
|
229 oop obj = _marking_stack.pop(); |
|
230 assert (obj->is_gc_marked(), "p must be marked"); |
|
231 follow_object(obj); |
|
232 } |
|
233 // Process ObjArrays one at a time to avoid marking stack bloat. |
|
234 if (!_objarray_stack.is_empty()) { |
|
235 ObjArrayTask task = _objarray_stack.pop(); |
|
236 follow_array(objArrayOop(task.obj()), task.index()); |
|
237 } |
|
238 } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty()); |
|
239 } |
|
240 |
|
241 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure; |
|
242 |
|
243 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); } |
|
244 |
|
245 void PreservedMark::adjust_pointer() { |
|
246 MarkSweep::adjust_pointer(&_obj); |
|
247 } |
|
248 |
|
249 void PreservedMark::restore() { |
|
250 _obj->set_mark(_mark); |
|
251 } |
|
252 |
|
253 // We preserve the mark which should be replaced at the end and the location |
|
254 // that it will go. Note that the object that this markOop belongs to isn't |
|
255 // currently at that address but it will be after phase4 |
|
256 void MarkSweep::preserve_mark(oop obj, markOop mark) { |
|
257 // We try to store preserved marks in the to space of the new generation since |
|
258 // this is storage which should be available. Most of the time this should be |
|
259 // sufficient space for the marks we need to preserve but if it isn't we fall |
|
260 // back to using Stacks to keep track of the overflow. |
|
261 if (_preserved_count < _preserved_count_max) { |
|
262 _preserved_marks[_preserved_count++].init(obj, mark); |
|
263 } else { |
|
264 _preserved_mark_stack.push(mark); |
|
265 _preserved_oop_stack.push(obj); |
|
266 } |
|
267 } |
|
268 |
|
269 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure; |
|
270 |
|
271 template <typename T> |
|
272 void MarkSweep::AdjustPointerClosure::do_oop_nv(T* p) { adjust_pointer(p); } |
|
273 void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { do_oop_nv(p); } |
|
274 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); } |
|
275 |
|
276 void MarkSweep::adjust_marks() { |
|
277 assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(), |
|
278 "inconsistent preserved oop stacks"); |
|
279 |
|
280 // adjust the oops we saved earlier |
|
281 for (size_t i = 0; i < _preserved_count; i++) { |
|
282 _preserved_marks[i].adjust_pointer(); |
|
283 } |
|
284 |
|
285 // deal with the overflow stack |
|
286 StackIterator<oop, mtGC> iter(_preserved_oop_stack); |
|
287 while (!iter.is_empty()) { |
|
288 oop* p = iter.next_addr(); |
|
289 adjust_pointer(p); |
|
290 } |
|
291 } |
|
292 |
|
293 void MarkSweep::restore_marks() { |
|
294 assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(), |
|
295 "inconsistent preserved oop stacks"); |
|
296 if (PrintGC && Verbose) { |
|
297 gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks", |
|
298 _preserved_count + _preserved_oop_stack.size()); |
|
299 } |
|
300 |
|
301 // restore the marks we saved earlier |
|
302 for (size_t i = 0; i < _preserved_count; i++) { |
|
303 _preserved_marks[i].restore(); |
|
304 } |
|
305 |
|
306 // deal with the overflow |
|
307 while (!_preserved_oop_stack.is_empty()) { |
|
308 oop obj = _preserved_oop_stack.pop(); |
|
309 markOop mark = _preserved_mark_stack.pop(); |
|
310 obj->set_mark(mark); |
|
311 } |
|
312 } |
|
313 |
|
314 MarkSweep::IsAliveClosure MarkSweep::is_alive; |
|
315 |
|
316 bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); } |
|
317 |
|
318 MarkSweep::KeepAliveClosure MarkSweep::keep_alive; |
|
319 |
|
320 void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } |
|
321 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } |
|
322 |
|
323 void marksweep_init() { |
|
324 MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer(); |
|
325 MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer(); |
|
326 } |
|
327 |
|
328 int InstanceKlass::oop_ms_adjust_pointers(oop obj) { |
|
329 int size = size_helper(); |
|
330 oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure); |
|
331 return size; |
|
332 } |
|
333 |
|
334 int InstanceMirrorKlass::oop_ms_adjust_pointers(oop obj) { |
|
335 int size = oop_size(obj); |
|
336 InstanceKlass::oop_ms_adjust_pointers(obj); |
|
337 |
|
338 oop_oop_iterate_statics<true>(obj, &MarkSweep::adjust_pointer_closure); |
|
339 return size; |
|
340 } |
|
341 |
|
342 int InstanceClassLoaderKlass::oop_ms_adjust_pointers(oop obj) { |
|
343 return InstanceKlass::oop_ms_adjust_pointers(obj); |
|
344 } |
|
345 |
|
346 #ifdef ASSERT |
|
347 template <class T> static void trace_reference_gc(const char *s, oop obj, |
|
348 T* referent_addr, |
|
349 T* next_addr, |
|
350 T* discovered_addr) { |
|
351 if(TraceReferenceGC && PrintGCDetails) { |
|
352 gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj)); |
|
353 gclog_or_tty->print_cr(" referent_addr/* " PTR_FORMAT " / " |
|
354 PTR_FORMAT, p2i(referent_addr), |
|
355 p2i(referent_addr ? |
|
356 (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL)); |
|
357 gclog_or_tty->print_cr(" next_addr/* " PTR_FORMAT " / " |
|
358 PTR_FORMAT, p2i(next_addr), |
|
359 p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL)); |
|
360 gclog_or_tty->print_cr(" discovered_addr/* " PTR_FORMAT " / " |
|
361 PTR_FORMAT, p2i(discovered_addr), |
|
362 p2i(discovered_addr ? |
|
363 (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL)); |
|
364 } |
|
365 } |
|
366 #endif |
|
367 |
|
368 template <class T> void static adjust_object_specialized(oop obj) { |
|
369 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
|
370 MarkSweep::adjust_pointer(referent_addr); |
|
371 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
|
372 MarkSweep::adjust_pointer(next_addr); |
|
373 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
374 MarkSweep::adjust_pointer(discovered_addr); |
|
375 debug_only(trace_reference_gc("InstanceRefKlass::oop_ms_adjust_pointers", obj, |
|
376 referent_addr, next_addr, discovered_addr);) |
|
377 } |
|
378 |
|
379 int InstanceRefKlass::oop_ms_adjust_pointers(oop obj) { |
|
380 int size = size_helper(); |
|
381 InstanceKlass::oop_ms_adjust_pointers(obj); |
|
382 |
|
383 if (UseCompressedOops) { |
|
384 adjust_object_specialized<narrowOop>(obj); |
|
385 } else { |
|
386 adjust_object_specialized<oop>(obj); |
|
387 } |
|
388 return size; |
|
389 } |
|
390 |
|
391 int ObjArrayKlass::oop_ms_adjust_pointers(oop obj) { |
|
392 assert(obj->is_objArray(), "obj must be obj array"); |
|
393 objArrayOop a = objArrayOop(obj); |
|
394 // Get size before changing pointers. |
|
395 // Don't call size() or oop_size() since that is a virtual call. |
|
396 int size = a->object_size(); |
|
397 oop_oop_iterate_elements<true>(a, &MarkSweep::adjust_pointer_closure); |
|
398 return size; |
|
399 } |
|
400 |
|
401 int TypeArrayKlass::oop_ms_adjust_pointers(oop obj) { |
|
402 assert(obj->is_typeArray(), "must be a type array"); |
|
403 typeArrayOop t = typeArrayOop(obj); |
|
404 // Performance tweak: We skip iterating over the klass pointer since we |
|
405 // know that Universe::TypeArrayKlass never moves. |
|
406 return t->object_size(); |
|
407 } |