2389 ShenandoahConnectionMatrix* ShenandoahHeap::connection_matrix() { 2390 return _connection_matrix; 2391 } 2392 2393 ShenandoahPartialGC* ShenandoahHeap::partial_gc() { 2394 return _partial_gc; 2395 } 2396 2397 void ShenandoahHeap::do_partial_collection() { 2398 partial_gc()->do_partial_collection(); 2399 } 2400 2401 template<class T> 2402 class ShenandoahUpdateHeapRefsTask : public AbstractGangTask { 2403 private: 2404 T cl; 2405 ShenandoahHeap* _heap; 2406 ShenandoahHeapRegionSet* _regions; 2407 2408 public: 2409 ShenandoahUpdateHeapRefsTask() : 2410 AbstractGangTask("Concurrent Update References Task"), 2411 cl(T()), 2412 _heap(ShenandoahHeap::heap()), 2413 _regions(ShenandoahHeap::heap()->regions()) { 2414 _regions->clear_current_index(); 2415 } 2416 2417 void work(uint worker_id) { 2418 ShenandoahHeapRegion* r = _regions->claim_next(); 2419 while (r != NULL && ! _heap->cancelled_concgc()) { 2420 if (! _heap->in_collection_set(r) && 2421 ! r->is_empty()) { 2422 _heap->marked_object_oop_safe_iterate(r, &cl); 2423 } else if (_heap->in_collection_set(r)) { 2424 HeapWord* bottom = r->bottom(); 2425 HeapWord* top = _heap->complete_top_at_mark_start(r->bottom()); 2426 if (top > bottom) { 2427 _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); 2428 } 2429 } 2430 r = _regions->claim_next(); 2431 } 2432 } 2433 }; 2434 2435 void ShenandoahHeap::concurrent_update_heap_references() { 2436 _shenandoah_policy->record_phase_start(ShenandoahCollectorPolicy::conc_update_refs); 2437 if (UseShenandoahMatrix) { 2438 ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsMatrixClosure> task; 2439 workers()->run_task(&task); 2440 } else { 2441 ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsClosure> task; 2442 workers()->run_task(&task); 2443 } 2444 _shenandoah_policy->record_phase_end(ShenandoahCollectorPolicy::conc_update_refs); 2445 } 2446 2447 void ShenandoahHeap::prepare_update_refs() { 2448 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 2449 set_evacuation_in_progress_at_safepoint(false); 2450 set_update_refs_in_progress(true); 2451 ensure_parsability(true); 2452 connection_matrix()->clear_all(); 2453 for (uint i = 0; i < _num_regions; i++) { 2454 ShenandoahHeapRegion* r = _ordered_regions->get(i); 2455 r->set_concurrent_iteration_safe_limit(r->top()); 2456 } 2457 } 2458 2459 void ShenandoahHeap::finish_update_refs() { 2460 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 2461 2462 if (! cancelled_concgc()) { 2463 concurrentMark()->update_roots(ShenandoahCollectorPolicy::final_update_refs_roots); 2464 recycle_dirty_regions(); 2465 set_need_update_refs(false); 2466 2467 if (ShenandoahVerify) { 2468 verify_update_refs(); 2469 } 2470 2471 { 2472 // Rebuild the free set 2473 ShenandoahHeapLock hl(this); 2474 _free_regions->clear(); 2475 size_t end = _ordered_regions->active_regions(); 2476 for (size_t i = 0; i < end; i++) { 2477 ShenandoahHeapRegion* r = _ordered_regions->get(i); 2478 if (!r->is_humongous()) { 2479 assert (!in_collection_set(r), "collection set should be clear"); 2480 _free_regions->add_region(r); 2481 } 2482 } 2483 } 2484 } 2485 set_update_refs_in_progress(false); 2486 } 2487 2488 class ShenandoahVerifyUpdateRefsClosure : public ExtendedOopClosure { 2489 private: 2490 template <class T> 2491 void do_oop_work(T* p) { 2492 T o = oopDesc::load_heap_oop(p); 2493 if (! oopDesc::is_null(o)) { 2494 oop obj = oopDesc::decode_heap_oop_not_null(o); 2495 guarantee(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)), 2496 "must not be forwarded"); 2497 } 2498 } 2499 public: 2500 void do_oop(oop* p) { do_oop_work(p); } 2501 void do_oop(narrowOop* p) { do_oop_work(p); } | 2389 ShenandoahConnectionMatrix* ShenandoahHeap::connection_matrix() { 2390 return _connection_matrix; 2391 } 2392 2393 ShenandoahPartialGC* ShenandoahHeap::partial_gc() { 2394 return _partial_gc; 2395 } 2396 2397 void ShenandoahHeap::do_partial_collection() { 2398 partial_gc()->do_partial_collection(); 2399 } 2400 2401 template<class T> 2402 class ShenandoahUpdateHeapRefsTask : public AbstractGangTask { 2403 private: 2404 T cl; 2405 ShenandoahHeap* _heap; 2406 ShenandoahHeapRegionSet* _regions; 2407 2408 public: 2409 ShenandoahUpdateHeapRefsTask(ShenandoahHeapRegionSet* regions) : 2410 AbstractGangTask("Concurrent Update References Task"), 2411 cl(T()), 2412 _heap(ShenandoahHeap::heap()), 2413 _regions(regions) { 2414 } 2415 2416 void work(uint worker_id) { 2417 ShenandoahHeapRegion* r = _regions->claim_next(); 2418 while (r != NULL) { 2419 if (! _heap->in_collection_set(r) && 2420 ! r->is_empty()) { 2421 _heap->marked_object_oop_safe_iterate(r, &cl); 2422 } else if (_heap->in_collection_set(r)) { 2423 HeapWord* bottom = r->bottom(); 2424 HeapWord* top = _heap->complete_top_at_mark_start(r->bottom()); 2425 if (top > bottom) { 2426 _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); 2427 } 2428 } 2429 if (_heap->cancelled_concgc()) { 2430 return; 2431 } 2432 r = _regions->claim_next(); 2433 } 2434 } 2435 }; 2436 2437 void ShenandoahHeap::update_heap_references(ShenandoahHeapRegionSet* update_regions) { 2438 if (UseShenandoahMatrix) { 2439 ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsMatrixClosure> task(update_regions); 2440 workers()->run_task(&task); 2441 } else { 2442 ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsClosure> task(update_regions); 2443 workers()->run_task(&task); 2444 } 2445 } 2446 2447 void ShenandoahHeap::concurrent_update_heap_references() { 2448 _shenandoah_policy->record_phase_start(ShenandoahCollectorPolicy::conc_update_refs); 2449 ShenandoahHeapRegionSet* update_regions = regions(); 2450 update_regions->clear_current_index(); 2451 update_heap_references(update_regions); 2452 _shenandoah_policy->record_phase_end(ShenandoahCollectorPolicy::conc_update_refs); 2453 } 2454 2455 void ShenandoahHeap::prepare_update_refs() { 2456 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 2457 set_evacuation_in_progress_at_safepoint(false); 2458 set_update_refs_in_progress(true); 2459 ensure_parsability(true); 2460 if (UseShenandoahMatrix) { 2461 connection_matrix()->clear_all(); 2462 } 2463 for (uint i = 0; i < _num_regions; i++) { 2464 ShenandoahHeapRegion* r = _ordered_regions->get(i); 2465 r->set_concurrent_iteration_safe_limit(r->top()); 2466 } 2467 } 2468 2469 void ShenandoahHeap::finish_update_refs() { 2470 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 2471 2472 if (cancelled_concgc()) { 2473 // Finish updating references where we left off. 2474 clear_cancelled_concgc(); 2475 ShenandoahHeapRegionSet* update_regions = regions(); 2476 update_heap_references(update_regions); 2477 } 2478 2479 assert(! cancelled_concgc(), "Should have been done right before"); 2480 concurrentMark()->update_roots(ShenandoahCollectorPolicy::final_update_refs_roots); 2481 recycle_dirty_regions(); 2482 set_need_update_refs(false); 2483 2484 if (ShenandoahVerify) { 2485 verify_update_refs(); 2486 } 2487 2488 { 2489 // Rebuild the free set 2490 ShenandoahHeapLock hl(this); 2491 _free_regions->clear(); 2492 size_t end = _ordered_regions->active_regions(); 2493 for (size_t i = 0; i < end; i++) { 2494 ShenandoahHeapRegion* r = _ordered_regions->get(i); 2495 if (!r->is_humongous()) { 2496 assert (!in_collection_set(r), "collection set should be clear"); 2497 _free_regions->add_region(r); 2498 } 2499 } 2500 } 2501 set_update_refs_in_progress(false); 2502 } 2503 2504 class ShenandoahVerifyUpdateRefsClosure : public ExtendedOopClosure { 2505 private: 2506 template <class T> 2507 void do_oop_work(T* p) { 2508 T o = oopDesc::load_heap_oop(p); 2509 if (! oopDesc::is_null(o)) { 2510 oop obj = oopDesc::decode_heap_oop_not_null(o); 2511 guarantee(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)), 2512 "must not be forwarded"); 2513 } 2514 } 2515 public: 2516 void do_oop(oop* p) { do_oop_work(p); } 2517 void do_oop(narrowOop* p) { do_oop_work(p); } |