1505 { |
1505 { |
1506 ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs); |
1506 ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs); |
1507 make_parsable(true); |
1507 make_parsable(true); |
1508 } |
1508 } |
1509 |
1509 |
|
1510 // We are about to select the collection set, make sure it knows about |
|
1511 // current pinning status. Also, this allows trashing more regions that |
|
1512 // now have their pinning status dropped. |
|
1513 { |
|
1514 ShenandoahGCPhase phase(ShenandoahPhaseTimings::sync_pinned); |
|
1515 sync_pinned_region_status(); |
|
1516 } |
|
1517 |
1510 // Trash the collection set left over from previous cycle, if any. |
1518 // Trash the collection set left over from previous cycle, if any. |
1511 { |
1519 { |
1512 ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset); |
1520 ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset); |
1513 trash_cset_regions(); |
1521 trash_cset_regions(); |
1514 } |
1522 } |
1782 // the collection set, and then the pin reached the cset region. If we continue |
1790 // the collection set, and then the pin reached the cset region. If we continue |
1783 // the cycle here, we would trash the cset and alive objects in it. To avoid |
1791 // the cycle here, we would trash the cset and alive objects in it. To avoid |
1784 // it, we fail degeneration right away and slide into Full GC to recover. |
1792 // it, we fail degeneration right away and slide into Full GC to recover. |
1785 |
1793 |
1786 { |
1794 { |
|
1795 sync_pinned_region_status(); |
1787 collection_set()->clear_current_index(); |
1796 collection_set()->clear_current_index(); |
1788 |
1797 |
1789 ShenandoahHeapRegion* r; |
1798 ShenandoahHeapRegion* r; |
1790 while ((r = collection_set()->next()) != NULL) { |
1799 while ((r = collection_set()->next()) != NULL) { |
1791 if (r->is_pinned()) { |
1800 if (r->is_pinned()) { |
2146 void ShenandoahHeap::unregister_nmethod(nmethod* nm) { |
2155 void ShenandoahHeap::unregister_nmethod(nmethod* nm) { |
2147 ShenandoahCodeRoots::remove_nmethod(nm); |
2156 ShenandoahCodeRoots::remove_nmethod(nm); |
2148 } |
2157 } |
2149 |
2158 |
2150 oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) { |
2159 oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) { |
|
2160 heap_region_containing(o)->record_pin(); |
|
2161 return o; |
|
2162 } |
|
2163 |
|
2164 void ShenandoahHeap::unpin_object(JavaThread* thr, oop o) { |
|
2165 heap_region_containing(o)->record_unpin(); |
|
2166 } |
|
2167 |
|
2168 void ShenandoahHeap::sync_pinned_region_status() { |
2151 ShenandoahHeapLocker locker(lock()); |
2169 ShenandoahHeapLocker locker(lock()); |
2152 heap_region_containing(o)->make_pinned(); |
2170 |
2153 return o; |
2171 for (size_t i = 0; i < num_regions(); i++) { |
2154 } |
2172 ShenandoahHeapRegion *r = get_region(i); |
2155 |
2173 if (r->is_active()) { |
2156 void ShenandoahHeap::unpin_object(JavaThread* thr, oop o) { |
2174 if (r->is_pinned()) { |
2157 ShenandoahHeapLocker locker(lock()); |
2175 if (r->pin_count() == 0) { |
2158 heap_region_containing(o)->make_unpinned(); |
2176 r->make_unpinned(); |
2159 } |
2177 } |
|
2178 } else { |
|
2179 if (r->pin_count() > 0) { |
|
2180 r->make_pinned(); |
|
2181 } |
|
2182 } |
|
2183 } |
|
2184 } |
|
2185 |
|
2186 assert_pinned_region_status(); |
|
2187 } |
|
2188 |
|
2189 #ifdef ASSERT |
|
2190 void ShenandoahHeap::assert_pinned_region_status() { |
|
2191 for (size_t i = 0; i < num_regions(); i++) { |
|
2192 ShenandoahHeapRegion* r = get_region(i); |
|
2193 assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0), |
|
2194 "Region " SIZE_FORMAT " pinning status is inconsistent", i); |
|
2195 } |
|
2196 } |
|
2197 #endif |
2160 |
2198 |
2161 GCTimer* ShenandoahHeap::gc_timer() const { |
2199 GCTimer* ShenandoahHeap::gc_timer() const { |
2162 return _gc_timer; |
2200 return _gc_timer; |
2163 } |
2201 } |
2164 |
2202 |
2314 // Has to be done before cset is clear |
2352 // Has to be done before cset is clear |
2315 if (ShenandoahVerify) { |
2353 if (ShenandoahVerify) { |
2316 verifier()->verify_roots_in_to_space(); |
2354 verifier()->verify_roots_in_to_space(); |
2317 } |
2355 } |
2318 |
2356 |
|
2357 // Drop unnecessary "pinned" state from regions that does not have CP marks |
|
2358 // anymore, as this would allow trashing them below. |
|
2359 { |
|
2360 ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_sync_pinned); |
|
2361 sync_pinned_region_status(); |
|
2362 } |
|
2363 |
2319 { |
2364 { |
2320 ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset); |
2365 ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset); |
2321 trash_cset_regions(); |
2366 trash_cset_regions(); |
2322 } |
2367 } |
2323 |
2368 |