1219 };
1220
1221 class ShenandoahPrepareForUpdateRefsHandshakeClosure : public HandshakeClosure {
1222 public:
1223 explicit ShenandoahPrepareForUpdateRefsHandshakeClosure(char gc_state) :
1224 HandshakeClosure("Shenandoah Prepare for Update Refs"),
1225 _retire(ResizeTLAB), _propagator(gc_state) {}
1226
1227 void do_thread(Thread* thread) override {
1228 _propagator.do_thread(thread);
1229 if (ShenandoahThreadLocalData::gclab(thread) != nullptr) {
1230 _retire.do_thread(thread);
1231 }
1232 }
1233 private:
1234 ShenandoahRetireGCLABClosure _retire;
1235 ShenandoahGCStatePropagatorHandshakeClosure _propagator;
1236 };
1237
1238 void ShenandoahHeap::evacuate_collection_set(ShenandoahGeneration* generation, bool concurrent) {
1239 assert(generation->is_global(), "Only global generation expected here");
1240 ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1241 workers()->run_task(&task);
1242 }
1243
1244 void ShenandoahHeap::concurrent_prepare_for_update_refs() {
1245 {
1246 // Java threads take this lock while they are being attached and added to the list of threads.
1247 // If another thread holds this lock before we update the gc state, it will receive a stale
1248 // gc state, but they will have been added to the list of java threads and so will be corrected
1249 // by the following handshake.
1250 MutexLocker lock(Threads_lock);
1251
1252 // A cancellation at this point means the degenerated cycle must resume from update-refs.
1253 set_gc_state_concurrent(EVACUATION, false);
1254 set_gc_state_concurrent(WEAK_ROOTS, false);
1255 set_gc_state_concurrent(UPDATE_REFS, true);
1256 }
1257
1258 // This will propagate the gc state and retire gclabs and plabs for threads that require it.
1259 ShenandoahPrepareForUpdateRefsHandshakeClosure prepare_for_update_refs(_gc_state.raw_value());
1260
1261 // The handshake won't touch worker threads (or control thread, or VM thread), so do those separately.
1262 Threads::non_java_threads_do(&prepare_for_update_refs);
1263
1264 // Now retire gclabs and plabs and propagate gc_state for mutator threads
1265 Handshake::execute(&prepare_for_update_refs);
1266
1267 _update_refs_iterator.reset();
1268 }
1269
1270 class ShenandoahCompositeHandshakeClosure : public HandshakeClosure {
1271 HandshakeClosure* _handshake_1;
1272 HandshakeClosure* _handshake_2;
1273 public:
1274 ShenandoahCompositeHandshakeClosure(HandshakeClosure* handshake_1, HandshakeClosure* handshake_2) :
1275 HandshakeClosure(handshake_2->name()),
|
1219 };
1220
1221 class ShenandoahPrepareForUpdateRefsHandshakeClosure : public HandshakeClosure {
1222 public:
1223 explicit ShenandoahPrepareForUpdateRefsHandshakeClosure(char gc_state) :
1224 HandshakeClosure("Shenandoah Prepare for Update Refs"),
1225 _retire(ResizeTLAB), _propagator(gc_state) {}
1226
1227 void do_thread(Thread* thread) override {
1228 _propagator.do_thread(thread);
1229 if (ShenandoahThreadLocalData::gclab(thread) != nullptr) {
1230 _retire.do_thread(thread);
1231 }
1232 }
1233 private:
1234 ShenandoahRetireGCLABClosure _retire;
1235 ShenandoahGCStatePropagatorHandshakeClosure _propagator;
1236 };
1237
1238 void ShenandoahHeap::evacuate_collection_set(ShenandoahGeneration* generation, bool concurrent) {
1239 if (concurrent && ShenandoahWeakRootsEarly) {
1240 // Turn weak roots off now, so that weak barriers do not go slow.
1241 {
1242 MutexLocker lock(Threads_lock);
1243 set_gc_state_concurrent(WEAK_ROOTS, false);
1244 }
1245
1246 ShenandoahGCStatePropagatorHandshakeClosure propagate_gc_state(_gc_state.raw_value());
1247 Threads::non_java_threads_do(&propagate_gc_state);
1248 Handshake::execute(&propagate_gc_state);
1249 }
1250
1251 assert(generation->is_global(), "Only global generation expected here");
1252 ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1253 workers()->run_task(&task);
1254 }
1255
1256 void ShenandoahHeap::concurrent_prepare_for_update_refs() {
1257 {
1258 // Java threads take this lock while they are being attached and added to the list of threads.
1259 // If another thread holds this lock before we update the gc state, it will receive a stale
1260 // gc state, but they will have been added to the list of java threads and so will be corrected
1261 // by the following handshake.
1262 MutexLocker lock(Threads_lock);
1263
1264 // A cancellation at this point means the degenerated cycle must resume from update-refs.
1265 set_gc_state_concurrent(EVACUATION, false);
1266 set_gc_state_concurrent(UPDATE_REFS, true);
1267 if (!ShenandoahWeakRootsEarly) {
1268 set_gc_state_concurrent(WEAK_ROOTS, false);
1269 }
1270 }
1271
1272 // This will propagate the gc state and retire gclabs and plabs for threads that require it.
1273 ShenandoahPrepareForUpdateRefsHandshakeClosure prepare_for_update_refs(_gc_state.raw_value());
1274
1275 // The handshake won't touch worker threads (or control thread, or VM thread), so do those separately.
1276 Threads::non_java_threads_do(&prepare_for_update_refs);
1277
1278 // Now retire gclabs and plabs and propagate gc_state for mutator threads
1279 Handshake::execute(&prepare_for_update_refs);
1280
1281 _update_refs_iterator.reset();
1282 }
1283
1284 class ShenandoahCompositeHandshakeClosure : public HandshakeClosure {
1285 HandshakeClosure* _handshake_1;
1286 HandshakeClosure* _handshake_2;
1287 public:
1288 ShenandoahCompositeHandshakeClosure(HandshakeClosure* handshake_1, HandshakeClosure* handshake_2) :
1289 HandshakeClosure(handshake_2->name()),
|