blob: d0fb3a8fa2d505c482ceb89d243e85d38b83bb64 [file] [log] [blame]
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_RUNTIME_SAFEPOINTMECHANISM_INLINE_HPP
#define SHARE_RUNTIME_SAFEPOINTMECHANISM_INLINE_HPP
#include "runtime/safepointMechanism.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handshake.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/stackWatermarkSet.hpp"
// Caller is responsible for using a memory barrier if needed.
inline void SafepointMechanism::ThreadData::set_polling_page(uintptr_t poll_value) {
Atomic::store(&_polling_page, poll_value);
}
// Caller is responsible for using a memory barrier if needed.
inline void SafepointMechanism::ThreadData::set_polling_word(uintptr_t poll_value) {
Atomic::store(&_polling_word, poll_value);
}
// The acquire makes sure reading of polling page is done before
// the reading the handshake operation or the global state
inline uintptr_t SafepointMechanism::ThreadData::get_polling_word() {
return Atomic::load_acquire(&_polling_word);
}
bool SafepointMechanism::local_poll_armed(JavaThread* thread) {
return thread->poll_data()->get_polling_word() & poll_bit();
}
bool SafepointMechanism::global_poll() {
return (SafepointSynchronize::_state != SafepointSynchronize::_not_synchronized);
}
bool SafepointMechanism::should_process(JavaThread* thread, bool allow_suspend) {
if (!local_poll_armed(thread)) {
return false;
}
if (global_poll() || // Safepoint
thread->handshake_state()->has_operation(allow_suspend, false /* check_async_exception */) || // Handshake
!StackWatermarkSet::processing_started(thread)) { // StackWatermark processing is not started
return true;
}
// It has boiled down to two possibilities:
// 1: We have nothing to process, this just a disarm poll.
// 2: We have a suspend or async exception handshake, which cannot be processed.
// We update the poll value in case of a disarm, to reduce false positives.
update_poll_values(thread);
return false;
}
void SafepointMechanism::process_if_requested(JavaThread* thread, bool allow_suspend, bool check_async_exception) {
// Check NoSafepointVerifier. This also clears unhandled oops if CheckUnhandledOops is used.
thread->check_possible_safepoint();
if (local_poll_armed(thread)) {
process(thread, allow_suspend, check_async_exception);
}
}
void SafepointMechanism::process_if_requested_with_exit_check(JavaThread* thread, bool check_async_exception) {
process_if_requested(thread, true /* allow_suspend */, check_async_exception);
if (thread->has_special_runtime_exit_condition()) {
thread->handle_special_runtime_exit_condition();
}
}
void SafepointMechanism::arm_local_poll(JavaThread* thread) {
thread->poll_data()->set_polling_word(_poll_word_armed_value);
thread->poll_data()->set_polling_page(_poll_page_armed_value);
}
void SafepointMechanism::disarm_local_poll(JavaThread* thread) {
thread->poll_data()->set_polling_word(_poll_word_disarmed_value);
thread->poll_data()->set_polling_page(_poll_page_disarmed_value);
}
void SafepointMechanism::arm_local_poll_release(JavaThread* thread) {
OrderAccess::release();
thread->poll_data()->set_polling_word(_poll_word_armed_value);
thread->poll_data()->set_polling_page(_poll_page_armed_value);
}
#endif // SHARE_RUNTIME_SAFEPOINTMECHANISM_INLINE_HPP