8263375: Support stack watermarks in Zero VM

Reviewed-by: eosterlund
This commit is contained in:
Aleksey Shipilev 2021-09-02 08:00:45 +00:00
parent 6cfe314262
commit 857a930bde
5 changed files with 44 additions and 21 deletions

View file

@ -34,6 +34,7 @@
#include "runtime/frame.inline.hpp" #include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/signature.hpp" #include "runtime/signature.hpp"
#include "runtime/stackWatermarkSet.hpp"
#include "vmreg_zero.inline.hpp" #include "vmreg_zero.inline.hpp"
#ifdef ASSERT #ifdef ASSERT
@ -82,10 +83,15 @@ frame frame::sender(RegisterMap* map) const {
// sender_for_xxx methods update this accordingly. // sender_for_xxx methods update this accordingly.
map->set_include_argument_oops(false); map->set_include_argument_oops(false);
if (is_entry_frame()) frame result = zeroframe()->is_entry_frame() ?
return sender_for_entry_frame(map); sender_for_entry_frame(map) :
else sender_for_nonentry_frame(map);
return sender_for_nonentry_frame(map);
if (map->process_frames()) {
StackWatermarkSet::on_iteration(map->thread(), result);
}
return result;
} }
BasicObjectLock* frame::interpreter_frame_monitor_begin() const { BasicObjectLock* frame::interpreter_frame_monitor_begin() const {

View file

@ -32,6 +32,8 @@
class VM_Version : public Abstract_VM_Version { class VM_Version : public Abstract_VM_Version {
public: public:
static void initialize(); static void initialize();
constexpr static bool supports_stack_watermark_barrier() { return true; }
}; };
#endif // CPU_ZERO_VM_VERSION_ZERO_HPP #endif // CPU_ZERO_VM_VERSION_ZERO_HPP

View file

@ -200,6 +200,18 @@ void ZeroInterpreter::main_loop(int recurse, TRAPS) {
} }
fixup_after_potential_safepoint(); fixup_after_potential_safepoint();
// If we are unwinding, notify the stack watermarks machinery.
// Should do this before resetting the frame anchor.
if (istate->msg() == BytecodeInterpreter::return_from_method ||
istate->msg() == BytecodeInterpreter::do_osr) {
stack_watermark_unwind_check(thread);
} else {
assert(istate->msg() == BytecodeInterpreter::call_method ||
istate->msg() == BytecodeInterpreter::more_monitors ||
istate->msg() == BytecodeInterpreter::throwing_exception,
"Should be one of these otherwise");
}
// Clear the frame anchor // Clear the frame anchor
thread->reset_last_Java_frame(); thread->reset_last_Java_frame();
@ -436,6 +448,10 @@ int ZeroInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
thread->set_thread_state(_thread_in_Java); thread->set_thread_state(_thread_in_Java);
fixup_after_potential_safepoint(); fixup_after_potential_safepoint();
// Notify the stack watermarks machinery that we are unwinding.
// Should do this before resetting the frame anchor.
stack_watermark_unwind_check(thread);
// Clear the frame anchor // Clear the frame anchor
thread->reset_last_Java_frame(); thread->reset_last_Java_frame();
@ -869,3 +885,13 @@ address ZeroInterpreter::remove_activation_early_entry(TosState state) {
bool ZeroInterpreter::contains(address pc) { bool ZeroInterpreter::contains(address pc) {
return false; // make frame::print_value_on work return false; // make frame::print_value_on work
} }
void ZeroInterpreter::stack_watermark_unwind_check(JavaThread* thread) {
// If frame pointer is in the danger zone, notify the runtime that
// it needs to act before continuing the unwinding.
uintptr_t fp = (uintptr_t)thread->last_Java_fp();
uintptr_t watermark = thread->poll_data()->get_polling_word();
if (fp > watermark) {
InterpreterRuntime::at_unwind(thread);
}
}

View file

@ -39,6 +39,9 @@
static int empty_entry(Method* method, intptr_t UNUSED, TRAPS); static int empty_entry(Method* method, intptr_t UNUSED, TRAPS);
static int Reference_get_entry(Method* method, intptr_t UNUSED, TRAPS); static int Reference_get_entry(Method* method, intptr_t UNUSED, TRAPS);
// Stack watermark machinery
static void stack_watermark_unwind_check(JavaThread* thread);
public: public:
// Main loop of normal_entry // Main loop of normal_entry
static void main_loop(int recurse, TRAPS); static void main_loop(int recurse, TRAPS);

View file

@ -107,7 +107,7 @@
There really shouldn't be any handles remaining to trash but this is cheap There really shouldn't be any handles remaining to trash but this is cheap
in relation to a safepoint. in relation to a safepoint.
*/ */
#define SAFEPOINT \ #define RETURN_SAFEPOINT \
if (SafepointMechanism::should_process(THREAD)) { \ if (SafepointMechanism::should_process(THREAD)) { \
HandleMarkCleaner __hmc(THREAD); \ HandleMarkCleaner __hmc(THREAD); \
CALL_VM(SafepointMechanism::process_if_requested_with_exit_check(THREAD, true /* check asyncs */), \ CALL_VM(SafepointMechanism::process_if_requested_with_exit_check(THREAD, true /* check asyncs */), \
@ -1331,23 +1331,15 @@ run:
CASE(_areturn): CASE(_areturn):
CASE(_ireturn): CASE(_ireturn):
CASE(_freturn): CASE(_freturn):
{
// Allow a safepoint before returning to frame manager.
SAFEPOINT;
goto handle_return;
}
CASE(_lreturn): CASE(_lreturn):
CASE(_dreturn): CASE(_dreturn):
{ CASE(_return): {
// Allow a safepoint before returning to frame manager. // Allow a safepoint before returning to frame manager.
SAFEPOINT; RETURN_SAFEPOINT;
goto handle_return; goto handle_return;
} }
CASE(_return_register_finalizer): { CASE(_return_register_finalizer): {
oop rcvr = LOCALS_OBJECT(0); oop rcvr = LOCALS_OBJECT(0);
VERIFY_OOP(rcvr); VERIFY_OOP(rcvr);
if (rcvr->klass()->has_finalizer()) { if (rcvr->klass()->has_finalizer()) {
@ -1355,12 +1347,6 @@ run:
} }
goto handle_return; goto handle_return;
} }
CASE(_return): {
// Allow a safepoint before returning to frame manager.
SAFEPOINT;
goto handle_return;
}
/* Array access byte-codes */ /* Array access byte-codes */