14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shared/gcTraceTime.inline.hpp"
26 #include "gc/shared/workgroup.hpp"
27 #include "gc/shared/taskqueue.inline.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
29 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
30 #include "gc/shenandoah/shenandoahConnectionMatrix.inline.hpp"
31 #include "gc/shenandoah/shenandoahFreeSet.hpp"
32 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
33 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
34 #include "gc/shenandoah/shenandoahPartialGC.hpp"
35 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
36 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
37 #include "memory/iterator.hpp"
38
39 class PartialEvacuateUpdateRootsClosure : public OopClosure {
40 ShenandoahPartialGC* _partial_gc;
41 Thread* _thread;
42 SCMObjToScanQueue* _queue;
43 private:
44 template <class T>
45 void do_oop_work(T* p) { _partial_gc->process_oop<T, false>(p, _thread, _queue); }
46 public:
47 PartialEvacuateUpdateRootsClosure(SCMObjToScanQueue* q) :
48 _partial_gc(ShenandoahHeap::heap()->partial_gc()),
49 _thread(Thread::current()), _queue(q) {}
50 void do_oop(oop* p) {
51 assert(! ShenandoahHeap::heap()->is_in_reserved(p), "sanity");
52 do_oop_work(p);
53 }
54 void do_oop(narrowOop* p) { do_oop_work(p); }
55 };
56
57 class PartialEvacuateUpdateHeapClosure : public ExtendedOopClosure {
58 ShenandoahPartialGC* _partial_gc;
59 Thread* _thread;
60 SCMObjToScanQueue* _queue;
61 private:
62 template <class T>
63 void do_oop_work(T* p) {
64 _partial_gc->process_oop<T, true>(p, _thread, _queue);
65 }
66 public:
67 PartialEvacuateUpdateHeapClosure(SCMObjToScanQueue* q) :
68 _partial_gc(ShenandoahHeap::heap()->partial_gc()),
69 _thread(Thread::current()), _queue(q) {}
70 void do_oop(oop* p) { do_oop_work(p); }
71 void do_oop(narrowOop* p) { do_oop_work(p); }
72 };
73
74 class ShenandoahPartialCollectionTask : public AbstractGangTask {
75 private:
76 ShenandoahRootProcessor* _rp;
77 ParallelTaskTerminator* _terminator;
78 ShenandoahHeapRegionSet* _root_regions;
79 ShenandoahHeap* _heap;
80 public:
81 ShenandoahPartialCollectionTask(ShenandoahRootProcessor* rp,
82 ParallelTaskTerminator* terminator,
83 ShenandoahHeapRegionSet* root_regions) :
84 AbstractGangTask("Shenandoah Partial Collection"),
85 _rp(rp), _terminator(terminator), _root_regions(root_regions),
86 _heap(ShenandoahHeap::heap()) {}
87
88 void work(uint worker_id) {
89 ShenandoahConnectionMatrix* matrix = _heap->connection_matrix();
90 SCMObjToScanQueueSet* queues = _heap->partial_gc()->task_queues();
91 SCMObjToScanQueue* q = queues->queue(worker_id);
92
93 // Step 1: Process ordinary GC roots.
305 HeapWord* top = _heap->complete_top_at_mark_start(r->bottom());
306 if (top > bottom) {
307 _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top));
308 }
309 r->recycle();
310 _heap->free_regions()->add_region(r);
311 }
312
313 reset();
314 }
315 }
316
317 policy->record_phase_end(ShenandoahCollectorPolicy::partial_gc);
318 _heap->gc_timer()->register_gc_end();
319 }
320
321 void ShenandoahPartialGC::reset() {
322 _heap->collection_set()->clear();
323 _heap->clear_cset_fast_test();
324 _root_regions->clear();
325 }
326
327 template <class T, bool UPDATE_MATRIX>
328 void ShenandoahPartialGC::process_oop(T* p, Thread* thread, SCMObjToScanQueue* queue) {
329 T o = oopDesc::load_heap_oop(p);
330 if (! oopDesc::is_null(o)) {
331 oop obj = oopDesc::decode_heap_oop_not_null(o);
332 if (_heap->in_collection_set(obj)) {
333 oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
334 if (oopDesc::unsafe_equals(obj, forw)) {
335 bool evacuated = false;
336 forw = _heap->evacuate_object(obj, thread, evacuated);
337
338 // Only the thread that succeeded evacuating this object pushes it to its work queue.
339 if (evacuated) {
340 assert(forw->is_oop(), "sanity");
341 bool succeeded = queue->push(SCMTask(forw));
342 assert(succeeded, "must succeed to push to task queue");
343 }
344 }
345 assert(! oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must be evacuated");
346 // Update reference.
347 oopDesc::encode_store_heap_oop_not_null(p, forw);
348 obj = forw; // For matrix update below.
349 }
350 if (UPDATE_MATRIX) {
351 #ifdef ASSERT
352 oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
353 assert(oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must not be evacuated: "PTR_FORMAT" -> "PTR_FORMAT, p2i(obj), p2i(forw));
354 #endif
355 _matrix->set_connected(p, obj);
356 }
357 }
358 }
359
360 SCMObjToScanQueueSet* ShenandoahPartialGC::task_queues() {
361 return _task_queues;
362 }
|
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shared/gcTraceTime.inline.hpp"
26 #include "gc/shared/workgroup.hpp"
27 #include "gc/shared/taskqueue.inline.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
29 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
30 #include "gc/shenandoah/shenandoahConnectionMatrix.inline.hpp"
31 #include "gc/shenandoah/shenandoahFreeSet.hpp"
32 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
33 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
34 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
35 #include "gc/shenandoah/shenandoahPartialGC.hpp"
36 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
37 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
38 #include "memory/iterator.hpp"
39
40 class PartialEvacuateUpdateRootsClosure : public OopClosure {
41 ShenandoahPartialGC* _partial_gc;
42 Thread* _thread;
43 SCMObjToScanQueue* _queue;
44 private:
45 template <class T>
46 void do_oop_work(T* p) { _partial_gc->process_oop<T, false>(p, _thread, _queue); }
47 public:
48 PartialEvacuateUpdateRootsClosure(SCMObjToScanQueue* q) :
49 _partial_gc(ShenandoahHeap::heap()->partial_gc()),
50 _thread(Thread::current()), _queue(q) {}
51 void do_oop(oop* p) {
52 assert(! ShenandoahHeap::heap()->is_in_reserved(p), "sanity");
53 do_oop_work(p);
54 }
55 void do_oop(narrowOop* p) { do_oop_work(p); }
56 };
57
58 class ShenandoahPartialCollectionTask : public AbstractGangTask {
59 private:
60 ShenandoahRootProcessor* _rp;
61 ParallelTaskTerminator* _terminator;
62 ShenandoahHeapRegionSet* _root_regions;
63 ShenandoahHeap* _heap;
64 public:
65 ShenandoahPartialCollectionTask(ShenandoahRootProcessor* rp,
66 ParallelTaskTerminator* terminator,
67 ShenandoahHeapRegionSet* root_regions) :
68 AbstractGangTask("Shenandoah Partial Collection"),
69 _rp(rp), _terminator(terminator), _root_regions(root_regions),
70 _heap(ShenandoahHeap::heap()) {}
71
72 void work(uint worker_id) {
73 ShenandoahConnectionMatrix* matrix = _heap->connection_matrix();
74 SCMObjToScanQueueSet* queues = _heap->partial_gc()->task_queues();
75 SCMObjToScanQueue* q = queues->queue(worker_id);
76
77 // Step 1: Process ordinary GC roots.
289 HeapWord* top = _heap->complete_top_at_mark_start(r->bottom());
290 if (top > bottom) {
291 _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top));
292 }
293 r->recycle();
294 _heap->free_regions()->add_region(r);
295 }
296
297 reset();
298 }
299 }
300
301 policy->record_phase_end(ShenandoahCollectorPolicy::partial_gc);
302 _heap->gc_timer()->register_gc_end();
303 }
304
305 void ShenandoahPartialGC::reset() {
306 _heap->collection_set()->clear();
307 _heap->clear_cset_fast_test();
308 _root_regions->clear();
309 }
310
311 SCMObjToScanQueueSet* ShenandoahPartialGC::task_queues() {
312 return _task_queues;
313 }
|