< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp

Print this page
rev 10496 : [backport] Rename "cancel_concgc" to "cancel_gc"
rev 10498 : [backport] Move heuristics from ShCollectorPolicy to ShHeap
rev 10525 : [backport] Replace ShBarrierSet* casts with accessor
rev 10532 : [backport] Apply ShenandoahEvacOOMScope only for evac-taking paths in ShenandoahBarrierSet
rev 10533 : [backport] Replace risky SBS::need_update_refs_barrier with straightforward check
rev 10534 : [backport] Pre-filter oops before enqueing them in SBS slowpaths
rev 10551 : [backport] Remove safe_equals()
rev 10594 : [backport] Split write barrier paths for mutator and GC workers
rev 10596 : [backport] WB slowpath should assist with evacuation of adjacent objects
rev 10610 : [backport] Evac assist should touch marked objects only
rev 10614 : [backport] Replace custom asserts with shenandoah_assert_*


  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  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_implementation/g1/g1SATBCardTableModRefBS.hpp"
  26 #include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
  27 #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp"
  29 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"

  30 #include "runtime/interfaceSupport.hpp"
  31 
  32 class ShenandoahUpdateRefsForOopClosure: public ExtendedOopClosure {
  33 private:
  34   ShenandoahHeap* _heap;


  35   template <class T>
  36   inline void do_oop_work(T* p) {
  37     _heap->maybe_update_with_forwarded(p);
  38   }
  39 public:
  40   ShenandoahUpdateRefsForOopClosure() : _heap(ShenandoahHeap::heap()) {
  41     assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
  42   }
  43   void do_oop(oop* p)       { do_oop_work(p); }
  44   void do_oop(narrowOop* p) { do_oop_work(p); }
  45 };
  46 
  47 ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
  48   BarrierSet(),
  49   _heap(heap)
  50 {
  51   _kind = BarrierSet::ShenandoahBarrierSet;
  52 }
  53 
  54 void ShenandoahBarrierSet::print_on(outputStream* st) const {
  55   st->print("ShenandoahBarrierSet");
  56 }
  57 
  58 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
  59   return bsn == BarrierSet::ShenandoahBarrierSet;
  60 }


 137   Unimplemented();
 138 }
 139 
 140 void ShenandoahBarrierSet::resize_covered_region(MemRegion mr) {
 141   Unimplemented();
 142 }
 143 
 144 void ShenandoahBarrierSet::write_prim_array(MemRegion mr) {
 145   Unimplemented();
 146 }
 147 
 148 void ShenandoahBarrierSet::write_prim_field(HeapWord* hw, size_t s , juint x, juint y) {
 149   Unimplemented();
 150 }
 151 
 152 bool ShenandoahBarrierSet::write_prim_needs_barrier(HeapWord* hw, size_t s, juint x, juint y) {
 153   Unimplemented();
 154   return false;
 155 }
 156 
 157 bool ShenandoahBarrierSet::need_update_refs_barrier() {
 158   if (_heap->shenandoahPolicy()->update_refs()) {
 159     return _heap->is_update_refs_in_progress();
 160   } else {
 161     return _heap->is_concurrent_mark_in_progress() && _heap->has_forwarded_objects();
 162   }
 163 }
 164 
 165 void ShenandoahBarrierSet::write_ref_array_work(MemRegion r) {
 166   ShouldNotReachHere();
 167 }
 168 
 169 template <class T>
 170 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
 171   assert(UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled");
 172   ShenandoahEvacOOMScope oom_evac_scope;
 173   ShenandoahUpdateRefsForOopClosure cl;
 174   T* dst = (T*) start;
 175   for (size_t i = 0; i < count; i++) {
 176     cl.do_oop(dst++);
 177   }
 178 }
 179 
 180 void ShenandoahBarrierSet::write_ref_array(HeapWord* start, size_t count) {
 181   assert(UseShenandoahGC, "should be enabled");
 182   if (!ShenandoahCloneBarrier) return;
 183   if (!need_update_refs_barrier()) return;
 184 

 185   if (UseCompressedOops) {
 186     write_ref_array_loop<narrowOop>(start, count);
 187   } else {
 188     write_ref_array_loop<oop>(start, count);
 189   }
 190 }
 191 
 192 template <class T>
 193 void ShenandoahBarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
 194   assert (UseShenandoahGC && ShenandoahSATBBarrier, "Should be enabled");
 195 
 196   shenandoah_assert_not_in_cset_loc_except(dst, _heap->cancelled_concgc());
 197 
 198   if (! JavaThread::satb_mark_queue_set().is_active()) return;
 199   T* elem_ptr = dst;
 200   for (size_t i = 0; i < count; i++, elem_ptr++) {
 201     T heap_oop = oopDesc::load_heap_oop(elem_ptr);
 202     if (!oopDesc::is_null(heap_oop)) {
 203       G1SATBCardTableModRefBS::enqueue(oopDesc::decode_heap_oop_not_null(heap_oop));
 204     }
 205   }
 206 }
 207 
 208 void ShenandoahBarrierSet::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
 209   if (! dest_uninitialized && ShenandoahSATBBarrier) {
 210     write_ref_array_pre_work(dst, (size_t)count);
 211   }
 212 }
 213 
 214 void ShenandoahBarrierSet::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
 215   if (! dest_uninitialized && ShenandoahSATBBarrier) {
 216     write_ref_array_pre_work(dst, (size_t)count);
 217   }
 218 }
 219 
 220 template <class T>
 221 void ShenandoahBarrierSet::write_ref_field_pre_static(T* field, oop newVal) {
 222   T heap_oop = oopDesc::load_heap_oop(field);
 223 
 224   shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_concgc());
 225 
 226   if (!oopDesc::is_null(heap_oop)) {
 227     G1SATBCardTableModRefBS::enqueue(oopDesc::decode_heap_oop(heap_oop));
 228   }
 229 }
 230 
 231 template <class T>
 232 inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop newVal) {
 233   write_ref_field_pre_static(field, newVal);
 234 }
 235 
 236 // These are the more general virtual versions.
 237 void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {
 238   write_ref_field_pre_static(field, new_val);
 239 }
 240 
 241 void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {
 242   write_ref_field_pre_static(field, new_val);
 243 }
 244 
 245 void ShenandoahBarrierSet::write_ref_field_pre_work(void* field, oop new_val) {
 246   guarantee(false, "Not needed");
 247 }
 248 
 249 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
 250   shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_concgc());
 251   shenandoah_assert_not_forwarded_except  (v, o, o == NULL || _heap->cancelled_concgc() || !_heap->is_concurrent_mark_in_progress());
 252   shenandoah_assert_not_in_cset_except    (v, o, o == NULL || _heap->cancelled_concgc() || !_heap->is_concurrent_mark_in_progress());
 253 }
 254 
 255 void ShenandoahBarrierSet::write_region_work(MemRegion mr) {
 256   assert(UseShenandoahGC, "should be enabled");
 257   if (!ShenandoahCloneBarrier) return;
 258   if (! need_update_refs_barrier()) return;
 259 
 260   // This is called for cloning an object (see jvm.cpp) after the clone
 261   // has been made. We are not interested in any 'previous value' because
 262   // it would be NULL in any case. But we *are* interested in any oop*
 263   // that potentially need to be updated.
 264 
 265   ShenandoahEvacOOMScope oom_evac_scope;
 266   oop obj = oop(mr.start());
 267   assert(obj->is_oop(), "must be an oop");
 268   ShenandoahUpdateRefsForOopClosure cl;
 269   obj->oop_iterate(&cl);
 270 }
 271 
 272 oop ShenandoahBarrierSet::read_barrier(oop src) {
 273   // Check for forwarded objects, because on Full GC path we might deal with
 274   // non-trivial fwdptrs that contain Full GC specific metadata. We could check
 275   // for is_full_gc_in_progress(), but this also covers the case of stable heap,
 276   // which provides a bit of performance improvement.
 277   if (ShenandoahReadBarrier && _heap->has_forwarded_objects()) {
 278     return ShenandoahBarrierSet::resolve_forwarded(src);
 279   } else {
 280     return src;
 281   }
 282 }
 283 
 284 bool ShenandoahBarrierSet::obj_equals(oop obj1, oop obj2) {
 285   bool eq = oopDesc::unsafe_equals(obj1, obj2);
 286   if (! eq && ShenandoahAcmpBarrier) {
 287     OrderAccess::loadload();
 288     obj1 = resolve_forwarded(obj1);
 289     obj2 = resolve_forwarded(obj2);
 290     eq = oopDesc::unsafe_equals(obj1, obj2);
 291   }
 292   return eq;
 293 }
 294 
 295 bool ShenandoahBarrierSet::obj_equals(narrowOop obj1, narrowOop obj2) {
 296   return obj_equals(oopDesc::decode_heap_oop(obj1), oopDesc::decode_heap_oop(obj2));
 297 }
 298 
 299 JRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_JRT(oopDesc* src))
 300   oop result = ((ShenandoahBarrierSet*)oopDesc::bs())->write_barrier(src);
 301   return (oopDesc*) result;
 302 JRT_END
 303 
 304 IRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_IRT(oopDesc* src))
 305   oop result = ((ShenandoahBarrierSet*)oopDesc::bs())->write_barrier(src);
 306   return (oopDesc*) result;
 307 IRT_END
 308 













































 309 oop ShenandoahBarrierSet::write_barrier(oop obj) {
 310   if (ShenandoahWriteBarrier) {
 311     if (!oopDesc::is_null(obj)) {
 312       bool evac_in_progress = _heap->is_evacuation_in_progress();
 313       oop fwd = resolve_forwarded_not_null(obj);
 314       if (evac_in_progress &&
 315           _heap->in_collection_set(obj) &&
 316           oopDesc::unsafe_equals(obj, fwd)) {
 317         ShenandoahEvacOOMScope oom_evac_scope;
 318         bool evac;
 319         return _heap->evacuate_object(obj, Thread::current(), evac);





 320       } else {
 321         return fwd;
 322       }
 323     }
 324   }
 325   return obj;
 326 }
 327 
 328 #ifdef ASSERT
 329 void ShenandoahBarrierSet::verify_safe_oop(oop p) {
 330   shenandoah_assert_not_in_cset_except(NULL, p, (p == NULL) || ShenandoahHeap::heap()->cancelled_concgc());
 331 }

 332 
 333 void ShenandoahBarrierSet::verify_safe_oop(narrowOop p) {
 334   verify_safe_oop(oopDesc::decode_heap_oop(p));
 335 }
 336 #endif


  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  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_implementation/g1/g1SATBCardTableModRefBS.hpp"
  26 #include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
  27 #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp"
  29 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
  30 #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp"
  31 #include "runtime/interfaceSupport.hpp"
  32 
  33 class ShenandoahUpdateRefsForOopClosure: public ExtendedOopClosure {
  34 private:
  35   ShenandoahHeap* _heap;
  36   ShenandoahBarrierSet* _bs;
  37 
  38   template <class T>
  39   inline void do_oop_work(T* p) {
  40     _heap->maybe_update_with_forwarded(p);
  41   }
  42 public:
  43   ShenandoahUpdateRefsForOopClosure() : _heap(ShenandoahHeap::heap()), _bs(ShenandoahBarrierSet::barrier_set()) {
  44     assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
  45   }
  46   void do_oop(oop* p)       { do_oop_work(p); }
  47   void do_oop(narrowOop* p) { do_oop_work(p); }
  48 };
  49 
  50 ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
  51   BarrierSet(),
  52   _heap(heap)
  53 {
  54   _kind = BarrierSet::ShenandoahBarrierSet;
  55 }
  56 
  57 void ShenandoahBarrierSet::print_on(outputStream* st) const {
  58   st->print("ShenandoahBarrierSet");
  59 }
  60 
  61 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
  62   return bsn == BarrierSet::ShenandoahBarrierSet;
  63 }


 140   Unimplemented();
 141 }
 142 
 143 void ShenandoahBarrierSet::resize_covered_region(MemRegion mr) {
 144   Unimplemented();
 145 }
 146 
 147 void ShenandoahBarrierSet::write_prim_array(MemRegion mr) {
 148   Unimplemented();
 149 }
 150 
 151 void ShenandoahBarrierSet::write_prim_field(HeapWord* hw, size_t s , juint x, juint y) {
 152   Unimplemented();
 153 }
 154 
 155 bool ShenandoahBarrierSet::write_prim_needs_barrier(HeapWord* hw, size_t s, juint x, juint y) {
 156   Unimplemented();
 157   return false;
 158 }
 159 








 160 void ShenandoahBarrierSet::write_ref_array_work(MemRegion r) {
 161   ShouldNotReachHere();
 162 }
 163 
 164 template <class T>
 165 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
 166   assert(UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled");

 167   ShenandoahUpdateRefsForOopClosure cl;
 168   T* dst = (T*) start;
 169   for (size_t i = 0; i < count; i++) {
 170     cl.do_oop(dst++);
 171   }
 172 }
 173 
 174 void ShenandoahBarrierSet::write_ref_array(HeapWord* start, size_t count) {
 175   assert(UseShenandoahGC, "should be enabled");
 176   if (!ShenandoahCloneBarrier) return;
 177   if (!need_update_refs_barrier()) return;
 178 
 179   ShenandoahEvacOOMScope oom_evac_scope;
 180   if (UseCompressedOops) {
 181     write_ref_array_loop<narrowOop>(start, count);
 182   } else {
 183     write_ref_array_loop<oop>(start, count);
 184   }
 185 }
 186 
 187 template <class T>
 188 void ShenandoahBarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
 189   assert (UseShenandoahGC && ShenandoahSATBBarrier, "Should be enabled");
 190 
 191   shenandoah_assert_not_in_cset_loc_except(dst, _heap->cancelled_gc());
 192 
 193   if (! JavaThread::satb_mark_queue_set().is_active()) return;
 194   T* elem_ptr = dst;
 195   for (size_t i = 0; i < count; i++, elem_ptr++) {
 196     T heap_oop = oopDesc::load_heap_oop(elem_ptr);
 197     if (!oopDesc::is_null(heap_oop)) {
 198       enqueue(oopDesc::decode_heap_oop_not_null(heap_oop));
 199     }
 200   }
 201 }
 202 
 203 void ShenandoahBarrierSet::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
 204   if (! dest_uninitialized && ShenandoahSATBBarrier) {
 205     write_ref_array_pre_work(dst, (size_t)count);
 206   }
 207 }
 208 
 209 void ShenandoahBarrierSet::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
 210   if (! dest_uninitialized && ShenandoahSATBBarrier) {
 211     write_ref_array_pre_work(dst, (size_t)count);
 212   }
 213 }
 214 
 215 template <class T>
 216 void ShenandoahBarrierSet::write_ref_field_pre_static(T* field, oop newVal) {
 217   T heap_oop = oopDesc::load_heap_oop(field);
 218 
 219   shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_gc());
 220 
 221   if (!oopDesc::is_null(heap_oop)) {
 222     ShenandoahBarrierSet::barrier_set()->enqueue(oopDesc::decode_heap_oop(heap_oop));
 223   }
 224 }
 225 
 226 template <class T>
 227 inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop newVal) {
 228   write_ref_field_pre_static(field, newVal);
 229 }
 230 
 231 // These are the more general virtual versions.
 232 void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {
 233   write_ref_field_pre_static(field, new_val);
 234 }
 235 
 236 void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {
 237   write_ref_field_pre_static(field, new_val);
 238 }
 239 
 240 void ShenandoahBarrierSet::write_ref_field_pre_work(void* field, oop new_val) {
 241   guarantee(false, "Not needed");
 242 }
 243 
 244 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
 245   shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
 246   shenandoah_assert_not_forwarded_except  (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
 247   shenandoah_assert_not_in_cset_except    (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
 248 }
 249 
 250 void ShenandoahBarrierSet::write_region_work(MemRegion mr) {
 251   assert(UseShenandoahGC, "should be enabled");
 252   if (!ShenandoahCloneBarrier) return;
 253   if (! need_update_refs_barrier()) return;
 254 
 255   // This is called for cloning an object (see jvm.cpp) after the clone
 256   // has been made. We are not interested in any 'previous value' because
 257   // it would be NULL in any case. But we *are* interested in any oop*
 258   // that potentially need to be updated.
 259 
 260   ShenandoahEvacOOMScope oom_evac_scope;
 261   oop obj = oop(mr.start());
 262   shenandoah_assert_correct(NULL, obj);
 263   ShenandoahUpdateRefsForOopClosure cl;
 264   obj->oop_iterate(&cl);
 265 }
 266 
 267 oop ShenandoahBarrierSet::read_barrier(oop src) {
 268   // Check for forwarded objects, because on Full GC path we might deal with
 269   // non-trivial fwdptrs that contain Full GC specific metadata. We could check
 270   // for is_full_gc_in_progress(), but this also covers the case of stable heap,
 271   // which provides a bit of performance improvement.
 272   if (ShenandoahReadBarrier && _heap->has_forwarded_objects()) {
 273     return ShenandoahBarrierSet::resolve_forwarded(src);
 274   } else {
 275     return src;
 276   }
 277 }
 278 
 279 bool ShenandoahBarrierSet::obj_equals(oop obj1, oop obj2) {
 280   bool eq = oopDesc::unsafe_equals(obj1, obj2);
 281   if (! eq && ShenandoahAcmpBarrier) {
 282     OrderAccess::loadload();
 283     obj1 = resolve_forwarded(obj1);
 284     obj2 = resolve_forwarded(obj2);
 285     eq = oopDesc::unsafe_equals(obj1, obj2);
 286   }
 287   return eq;
 288 }
 289 
 290 bool ShenandoahBarrierSet::obj_equals(narrowOop obj1, narrowOop obj2) {
 291   return obj_equals(oopDesc::decode_heap_oop(obj1), oopDesc::decode_heap_oop(obj2));
 292 }
 293 
 294 JRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_JRT(oopDesc* src))
 295   oop result = ShenandoahBarrierSet::barrier_set()->write_barrier_mutator(src);
 296   return (oopDesc*) result;
 297 JRT_END
 298 
 299 IRT_LEAF(oopDesc*, ShenandoahBarrierSet::write_barrier_IRT(oopDesc* src))
 300   oop result = ShenandoahBarrierSet::barrier_set()->write_barrier_mutator(src);
 301   return (oopDesc*) result;
 302 IRT_END
 303 
 304 oop ShenandoahBarrierSet::write_barrier_mutator(oop obj) {
 305   assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled");
 306   assert(_heap->is_gc_in_progress_mask(ShenandoahHeap::EVACUATION), "evac should be in progress");
 307   shenandoah_assert_in_cset(NULL, obj);
 308 
 309   oop fwd = resolve_forwarded_not_null(obj);
 310   if (oopDesc::unsafe_equals(obj, fwd)) {
 311     ShenandoahEvacOOMScope oom_evac_scope;
 312     bool evac;
 313 
 314     Thread* thread = Thread::current();
 315     oop res_oop = _heap->evacuate_object(obj, thread, evac);
 316 
 317     // Since we are already here and paid the price of getting through runtime call adapters
 318     // and acquiring oom-scope, it makes sense to try and evacuate more adjacent objects,
 319     // thus amortizing the overhead. For sparsely live heaps, scan costs easily dominate
 320     // total assist costs, and can introduce a lot of evacuation latency. This is why we
 321     // only scan for _nearest_ N objects, regardless if they are eligible for evac or not.
 322     // The scan itself should also avoid touching the non-marked objects below TAMS, because
 323     // their metadata (notably, klasses) may be incorrect already.
 324 
 325     size_t max = ShenandoahEvacAssist;
 326     if (max > 0) {
 327       ShenandoahMarkingContext* ctx = _heap->complete_marking_context();
 328 
 329       ShenandoahHeapRegion* r = _heap->heap_region_containing(obj);
 330       assert(r->is_cset(), "sanity");
 331 
 332       HeapWord* cur = (HeapWord*)obj + obj->size() + BrooksPointer::word_size();
 333 
 334       size_t count = 0;
 335       while ((cur < r->top()) && ctx->is_marked(oop(cur)) && (count++ < max)) {
 336         oop cur_oop = oop(cur);
 337         if (oopDesc::unsafe_equals(cur_oop, resolve_forwarded_not_null(cur_oop))) {
 338           _heap->evacuate_object(cur_oop, thread, evac);
 339         }
 340         cur = cur + cur_oop->size() + BrooksPointer::word_size();
 341       }
 342     }
 343 
 344     return res_oop;
 345   }
 346   return fwd;
 347 }
 348 
 349 oop ShenandoahBarrierSet::write_barrier(oop obj) {
 350   if (ShenandoahWriteBarrier) {
 351     if (!oopDesc::is_null(obj)) {
 352       bool evac_in_progress = _heap->is_evacuation_in_progress();
 353       oop fwd = resolve_forwarded_not_null(obj);
 354       if (evac_in_progress &&
 355           _heap->in_collection_set(obj) &&
 356           oopDesc::unsafe_equals(obj, fwd)) {
 357         Thread *t = Thread::current();
 358         bool evac;
 359         if (t->is_Worker_thread()) {
 360           return _heap->evacuate_object(obj, t, evac);
 361         } else {
 362           ShenandoahEvacOOMScope oom_evac_scope;
 363           return _heap->evacuate_object(obj, t, evac);
 364         }
 365       } else {
 366         return fwd;
 367       }
 368     }
 369   }
 370   return obj;
 371 }
 372 
 373 void ShenandoahBarrierSet::enqueue(oop obj) {
 374   // Filter marked objects before hitting the SATB queues. The same predicate would
 375   // be used by SATBMQ::filter to eliminate already marked objects downstream, but
 376   // filtering here helps to avoid wasteful SATB queueing work to begin with.
 377   if (!_heap->requires_marking(obj)) return;
 378 
 379   G1SATBCardTableModRefBS::enqueue(obj);

 380 }

< prev index next >