When VM_ChangeSingleStep::doit changes interpreter table to safepoint table it will never be changed back when using handshakes. (handshakes are default on) I cannot find any code which installs the normal table. (untested)
SafepointSynchronize::end (now refactored into ::disarm_safepoint) used to always call Interpreter::ignore_safepoints();.
With handshakes it is conditioned on using global safepoint,
SafepointMechanism::uses_global_page_poll(), otherwise safepoint don't touch it.
This means that interpreter would be stuck with safepoint table forever, causing a massive slowdown.
Patch for fixing this is moving the ignore call outside of global safepoint branch, since it contains proper checks:
diff -r 9bd13d6dea77 src/hotspot/share/runtime/safepoint.cpp
--- a/src/hotspot/share/runtime/safepoint.cpp Tue Jul 02 13:20:27 2019 -0400
+++ b/src/hotspot/share/runtime/safepoint.cpp Tue Jul 02 22:31:36 2019 +0200
@@ -470,6 +470,7 @@
PageArmed = false;
- // Remove safepoint check from interpreter
- Interpreter::ignore_safepoints();
}
+ // Remove safepoint check from interpreter
+ Interpreter::ignore_safepoints();
+
OrderAccess::fence(); // keep read and write of _state from floating up
Needs to be investigated and fixed if I haven't missed something.
This would affect version 10 and forward.