8253180: ZGC: Implementation of JEP 376: ZGC: Concurrent Thread-Stack Processing

Reviewed-by: stefank, pliden, rehn, neliasso, coleenp, smonteith
This commit is contained in:
Erik Österlund 2020-10-09 08:40:33 +00:00
parent a2f651904d
commit b9873e1833
131 changed files with 2428 additions and 572 deletions

View file

@ -58,6 +58,7 @@
#include "runtime/safepoint.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stackWatermarkSet.inline.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/sweeper.hpp"
@ -497,10 +498,20 @@ bool SafepointSynchronize::is_cleanup_needed() {
return false;
}
class ParallelSPCleanupThreadClosure : public ThreadClosure {
public:
void do_thread(Thread* thread) {
if (thread->is_Java_thread()) {
StackWatermarkSet::start_processing(thread->as_Java_thread(), StackWatermarkKind::gc);
}
}
};
class ParallelSPCleanupTask : public AbstractGangTask {
private:
SubTasksDone _subtasks;
uint _num_workers;
bool _do_lazy_roots;
class Tracer {
private:
@ -522,9 +533,17 @@ public:
ParallelSPCleanupTask(uint num_workers) :
AbstractGangTask("Parallel Safepoint Cleanup"),
_subtasks(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS),
_num_workers(num_workers) {}
_num_workers(num_workers),
_do_lazy_roots(!VMThread::vm_operation()->skip_thread_oop_barriers() &&
Universe::heap()->uses_stack_watermark_barrier()) {}
void work(uint worker_id) {
if (_do_lazy_roots && _subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_LAZY_ROOT_PROCESSING)) {
Tracer t("lazy partial thread root processing");
ParallelSPCleanupThreadClosure cl;
Threads::threads_do(&cl);
}
if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_DEFLATE_MONITORS)) {
Tracer t("deflating idle monitors");
ObjectSynchronizer::do_safepoint_work();
@ -773,7 +792,7 @@ void SafepointSynchronize::block(JavaThread *thread) {
!thread->is_at_poll_safepoint() && (state != _thread_in_native_trans));
}
// cross_modify_fence is done by SafepointMechanism::process_operation_if_requested_slow
// cross_modify_fence is done by SafepointMechanism::process_if_requested
// which is the only caller here.
}
@ -936,7 +955,7 @@ void ThreadSafepointState::handle_polling_page_exception() {
frame stub_fr = thread()->last_frame();
CodeBlob* stub_cb = stub_fr.cb();
assert(stub_cb->is_safepoint_stub(), "must be a safepoint stub");
RegisterMap map(thread(), true);
RegisterMap map(thread(), true, false);
frame caller_fr = stub_fr.sender(&map);
// Should only be poll_return or poll
@ -961,6 +980,11 @@ void ThreadSafepointState::handle_polling_page_exception() {
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// We get here if compiled return polls found a reason to call into the VM.
// One condition for that is that the top frame is not yet safe to use.
// The following stack watermark barrier poll will catch such situations.
StackWatermarkSet::after_unwind(thread());
// Process pending operation
SafepointMechanism::process_if_requested(thread());
@ -992,7 +1016,7 @@ void ThreadSafepointState::handle_polling_page_exception() {
// Deoptimize frame if exception has been thrown.
if (thread()->has_pending_exception() ) {
RegisterMap map(thread(), true);
RegisterMap map(thread(), true, false);
frame caller_fr = stub_fr.sender(&map);
if (caller_fr.is_deoptimized_frame()) {
// The exception patch will destroy registers that are still