< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Print this page

1188       // There are two reasons to retire all plabs between old-gen evacuation passes.
1189       //  1. We need to make the plab memory parsable by remembered-set scanning.
1190       //  2. We need to establish a trustworthy UpdateWaterMark value within each old-gen heap region
1191       shenandoah_plab->retire();
1192 
1193       // Re-enable promotions for the next evacuation phase.
1194       shenandoah_plab->enable_promotions();
1195 
1196       // Reset the fill size for next evacuation phase.
1197       if (_resize && shenandoah_plab->desired_size() > 0) {
1198         shenandoah_plab->set_desired_size(0);
1199       }
1200     }
1201   }
1202 };
1203 
1204 class ShenandoahGCStatePropagatorHandshakeClosure : public HandshakeClosure {
1205 public:
1206   explicit ShenandoahGCStatePropagatorHandshakeClosure(char gc_state) :
1207     HandshakeClosure("Shenandoah GC State Change"),
1208     _gc_state(gc_state) {}
1209 
1210   void do_thread(Thread* thread) override {
1211     ShenandoahThreadLocalData::set_gc_state(thread, _gc_state);
1212   }
1213 private:
1214   char _gc_state;

1215 };
1216 
1217 class ShenandoahPrepareForUpdateRefsHandshakeClosure : public HandshakeClosure {
1218 public:
1219   explicit ShenandoahPrepareForUpdateRefsHandshakeClosure(char gc_state) :
1220     HandshakeClosure("Shenandoah Prepare for Update Refs"),
1221     _retire(ResizeTLAB), _propagator(gc_state) {}
1222 
1223   void do_thread(Thread* thread) override {
1224     _propagator.do_thread(thread);
1225     if (ShenandoahThreadLocalData::gclab(thread) != nullptr) {
1226       _retire.do_thread(thread);
1227     }
1228   }
1229 private:
1230   ShenandoahRetireGCLABClosure _retire;
1231   ShenandoahGCStatePropagatorHandshakeClosure _propagator;
1232 };
1233 
1234 void ShenandoahHeap::evacuate_collection_set(ShenandoahGeneration* generation, bool concurrent) {












1235   assert(generation->is_global(), "Only global generation expected here");
1236   ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1237   workers()->run_task(&task);
1238 }
1239 
1240 void ShenandoahHeap::concurrent_prepare_for_update_refs() {
1241   {
1242     // Java threads take this lock while they are being attached and added to the list of threads.
1243     // If another thread holds this lock before we update the gc state, it will receive a stale
1244     // gc state, but they will have been added to the list of java threads and so will be corrected
1245     // by the following handshake.
1246     MutexLocker lock(Threads_lock);
1247 
1248     // A cancellation at this point means the degenerated cycle must resume from update-refs.
1249     set_gc_state_concurrent(EVACUATION, false);
1250     set_gc_state_concurrent(WEAK_ROOTS, false);
1251     set_gc_state_concurrent(UPDATE_REFS, true);



1252   }
1253 
1254   // This will propagate the gc state and retire gclabs and plabs for threads that require it.
1255   ShenandoahPrepareForUpdateRefsHandshakeClosure prepare_for_update_refs(_gc_state.raw_value());
1256 
1257   // The handshake won't touch worker threads (or control thread, or VM thread), so do those separately.
1258   Threads::non_java_threads_do(&prepare_for_update_refs);
1259 
1260   // Now retire gclabs and plabs and propagate gc_state for mutator threads
1261   Handshake::execute(&prepare_for_update_refs);
1262 
1263   _update_refs_iterator.reset();
1264 }
1265 
1266 class ShenandoahCompositeHandshakeClosure : public HandshakeClosure {
1267   HandshakeClosure* _handshake_1;
1268   HandshakeClosure* _handshake_2;
1269   public:
1270     ShenandoahCompositeHandshakeClosure(HandshakeClosure* handshake_1, HandshakeClosure* handshake_2) :
1271       HandshakeClosure(handshake_2->name()),

1188       // There are two reasons to retire all plabs between old-gen evacuation passes.
1189       //  1. We need to make the plab memory parsable by remembered-set scanning.
1190       //  2. We need to establish a trustworthy UpdateWaterMark value within each old-gen heap region
1191       shenandoah_plab->retire();
1192 
1193       // Re-enable promotions for the next evacuation phase.
1194       shenandoah_plab->enable_promotions();
1195 
1196       // Reset the fill size for next evacuation phase.
1197       if (_resize && shenandoah_plab->desired_size() > 0) {
1198         shenandoah_plab->set_desired_size(0);
1199       }
1200     }
1201   }
1202 };
1203 
1204 class ShenandoahGCStatePropagatorHandshakeClosure : public HandshakeClosure {
1205 public:
1206   explicit ShenandoahGCStatePropagatorHandshakeClosure(char gc_state) :
1207     HandshakeClosure("Shenandoah GC State Change"),
1208     _gc_state(gc_state), _gc_state_fast(ShenandoahThreadLocalData::compute_gc_state_fast(gc_state)) {}
1209 
1210   void do_thread(Thread* thread) override {
1211     ShenandoahThreadLocalData::set_gc_state(thread, _gc_state, _gc_state_fast);
1212   }
1213 private:
1214   char _gc_state;
1215   char _gc_state_fast;
1216 };
1217 
1218 class ShenandoahPrepareForUpdateRefsHandshakeClosure : public HandshakeClosure {
1219 public:
1220   explicit ShenandoahPrepareForUpdateRefsHandshakeClosure(char gc_state) :
1221     HandshakeClosure("Shenandoah Prepare for Update Refs"),
1222     _retire(ResizeTLAB), _propagator(gc_state) {}
1223 
1224   void do_thread(Thread* thread) override {
1225     _propagator.do_thread(thread);
1226     if (ShenandoahThreadLocalData::gclab(thread) != nullptr) {
1227       _retire.do_thread(thread);
1228     }
1229   }
1230 private:
1231   ShenandoahRetireGCLABClosure _retire;
1232   ShenandoahGCStatePropagatorHandshakeClosure _propagator;
1233 };
1234 
1235 void ShenandoahHeap::evacuate_collection_set(ShenandoahGeneration* generation, bool concurrent) {
1236   if (concurrent && ShenandoahWeakRootsEarly) {
1237     // Turn weak roots off now, so that weak barriers do not go slow.
1238     {
1239       MutexLocker lock(Threads_lock);
1240       set_gc_state_concurrent(WEAK_ROOTS, false);
1241     }
1242 
1243     ShenandoahGCStatePropagatorHandshakeClosure propagate_gc_state(_gc_state.raw_value());
1244     Threads::non_java_threads_do(&propagate_gc_state);
1245     Handshake::execute(&propagate_gc_state);
1246   }
1247 
1248   assert(generation->is_global(), "Only global generation expected here");
1249   ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1250   workers()->run_task(&task);
1251 }
1252 
1253 void ShenandoahHeap::concurrent_prepare_for_update_refs() {
1254   {
1255     // Java threads take this lock while they are being attached and added to the list of threads.
1256     // If another thread holds this lock before we update the gc state, it will receive a stale
1257     // gc state, but they will have been added to the list of java threads and so will be corrected
1258     // by the following handshake.
1259     MutexLocker lock(Threads_lock);
1260 
1261     // A cancellation at this point means the degenerated cycle must resume from update-refs.
1262     set_gc_state_concurrent(EVACUATION, false);

1263     set_gc_state_concurrent(UPDATE_REFS, true);
1264     if (!ShenandoahWeakRootsEarly) {
1265       set_gc_state_concurrent(WEAK_ROOTS, false);
1266     }
1267   }
1268 
1269   // This will propagate the gc state and retire gclabs and plabs for threads that require it.
1270   ShenandoahPrepareForUpdateRefsHandshakeClosure prepare_for_update_refs(_gc_state.raw_value());
1271 
1272   // The handshake won't touch worker threads (or control thread, or VM thread), so do those separately.
1273   Threads::non_java_threads_do(&prepare_for_update_refs);
1274 
1275   // Now retire gclabs and plabs and propagate gc_state for mutator threads
1276   Handshake::execute(&prepare_for_update_refs);
1277 
1278   _update_refs_iterator.reset();
1279 }
1280 
1281 class ShenandoahCompositeHandshakeClosure : public HandshakeClosure {
1282   HandshakeClosure* _handshake_1;
1283   HandshakeClosure* _handshake_2;
1284   public:
1285     ShenandoahCompositeHandshakeClosure(HandshakeClosure* handshake_1, HandshakeClosure* handshake_2) :
1286       HandshakeClosure(handshake_2->name()),
< prev index next >