8282477: [x86, aarch64] vmassert(_last_Java_pc == NULL, "already walkable"); fails with async profiler

Reviewed-by: dholmes, mdoerr, dlong
This commit is contained in:
Johannes Bechberger 2022-05-04 07:54:52 +00:00 committed by Martin Doerr
parent ca9d039fd3
commit 4b2c82200f
17 changed files with 26 additions and 64 deletions

View File

@ -355,13 +355,9 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
// Since we are walking the stack now this nested anchor is obviously walkable
// even if it wasn't when it was stacked.
if (!jfa->walkable()) {
// Capture _last_Java_pc (if needed) and mark anchor walkable.
jfa->capture_last_Java_pc();
}
jfa->make_walkable();
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
fr.set_sp_is_trusted();
@ -836,20 +832,14 @@ frame::frame(void* sp, void* fp, void* pc) {
#endif
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
void JavaFrameAnchor::make_walkable() {
// last frame set?
if (last_Java_sp() == NULL) return;
// already walkable?
if (walkable()) return;
vmassert(Thread::current() == (Thread*)thread, "not current thread");
vmassert(last_Java_sp() != NULL, "not called from Java code?");
vmassert(last_Java_pc() == NULL, "already walkable");
capture_last_Java_pc();
_last_Java_pc = (address)_last_Java_sp[-1];
vmassert(walkable(), "something went wrong");
}
void JavaFrameAnchor::capture_last_Java_pc() {
vmassert(_last_Java_sp != NULL, "no last frame set");
vmassert(_last_Java_pc == NULL, "already walkable");
_last_Java_pc = (address)_last_Java_sp[-1];
}

View File

@ -65,8 +65,8 @@ public:
}
bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
void make_walkable(JavaThread* thread);
void capture_last_Java_pc(void);
void make_walkable();
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }

View File

@ -65,7 +65,7 @@ public:
// Always walkable
bool walkable(void) { return true; }
// Never any thing to do since we are always walkable and can find address of return addresses
void make_walkable(JavaThread* thread) { }
void make_walkable() { }
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }

View File

@ -67,7 +67,7 @@ public:
// Always walkable.
bool walkable(void) { return true; }
// Never any thing to do since we are always walkable and can find address of return addresses.
void make_walkable(JavaThread* thread) { }
void make_walkable() { }
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }

View File

@ -338,13 +338,9 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
// Since we are walking the stack now this nested anchor is obviously walkable
// even if it wasn't when it was stacked.
if (!jfa->walkable()) {
// Capture _last_Java_pc (if needed) and mark anchor walkable.
jfa->capture_last_Java_pc();
}
jfa->make_walkable();
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
}
@ -678,20 +674,13 @@ frame::frame(void* ptr_sp, void* ptr_fp, void* pc) {
#endif
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
void JavaFrameAnchor::make_walkable() {
// last frame set?
if (last_Java_sp() == NULL) { return; }
// already walkable?
if (walkable()) { return; }
vmassert(Thread::current() == (Thread*)thread, "not current thread");
vmassert(last_Java_sp() != NULL, "not called from Java code?");
vmassert(last_Java_pc() == NULL, "already walkable");
capture_last_Java_pc();
_last_Java_pc = (address)_last_Java_sp[-1];
vmassert(walkable(), "something went wrong");
}
void JavaFrameAnchor::capture_last_Java_pc() {
vmassert(_last_Java_sp != NULL, "no last frame set");
vmassert(_last_Java_pc == NULL, "already walkable");
_last_Java_pc = (address)_last_Java_sp[-1];
}

View File

@ -66,8 +66,8 @@ public:
}
bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
void make_walkable(JavaThread* thread);
void capture_last_Java_pc(void);
void make_walkable();
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }

View File

@ -72,7 +72,7 @@
// We don't have to flush registers, so the stack is always walkable.
inline bool walkable(void) { return true; }
inline void make_walkable(JavaThread* thread) { }
inline void make_walkable() { }
public:

View File

@ -341,13 +341,9 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
// Since we are walking the stack now this nested anchor is obviously walkable
// even if it wasn't when it was stacked.
if (!jfa->walkable()) {
// Capture _last_Java_pc (if needed) and mark anchor walkable.
jfa->capture_last_Java_pc();
}
jfa->make_walkable();
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
@ -377,13 +373,9 @@ frame frame::sender_for_optimized_entry_frame(RegisterMap* map) const {
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
// Since we are walking the stack now this nested anchor is obviously walkable
// even if it wasn't when it was stacked.
if (!jfa->walkable()) {
// Capture _last_Java_pc (if needed) and mark anchor walkable.
jfa->capture_last_Java_pc();
}
jfa->make_walkable();
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
@ -720,20 +712,12 @@ frame::frame(void* sp, void* fp, void* pc) {
#endif
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
void JavaFrameAnchor::make_walkable() {
// last frame set?
if (last_Java_sp() == NULL) return;
// already walkable?
if (walkable()) return;
vmassert(Thread::current() == (Thread*)thread, "not current thread");
vmassert(last_Java_sp() != NULL, "not called from Java code?");
vmassert(last_Java_pc() == NULL, "already walkable");
capture_last_Java_pc();
_last_Java_pc = (address)_last_Java_sp[-1];
vmassert(walkable(), "something went wrong");
}
void JavaFrameAnchor::capture_last_Java_pc() {
vmassert(_last_Java_sp != NULL, "no last frame set");
vmassert(_last_Java_pc == NULL, "already walkable");
_last_Java_pc = (address)_last_Java_sp[-1];
}

View File

@ -63,8 +63,7 @@ public:
}
bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
void make_walkable(JavaThread* thread);
void capture_last_Java_pc(void);
void make_walkable();
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }

View File

@ -73,7 +73,7 @@
return true;
}
void make_walkable(JavaThread* thread) {
void make_walkable() {
// nothing to do
}

View File

@ -155,7 +155,7 @@ public:
thread->push_jni_handle_block();
assert(thread == JavaThread::current(), "thread must be current!");
thread->frame_anchor()->make_walkable(thread);
thread->frame_anchor()->make_walkable();
};
~JvmtiEventMark() {

View File

@ -525,7 +525,7 @@ bool HandshakeState::process_by_self(bool allow_suspend, bool check_async_except
assert(Thread::current() == _handshakee, "should call from _handshakee");
assert(!_handshakee->is_terminated(), "should not be a terminated thread");
_handshakee->frame_anchor()->make_walkable(_handshakee);
_handshakee->frame_anchor()->make_walkable();
// Threads shouldn't block if they are in the middle of printing, but...
ttyLocker::break_tty_lock_for_safepoint(os::current_thread_id());

View File

@ -113,7 +113,7 @@ class ThreadStateTransition : public StackObj {
thread->check_possible_safepoint();
// Once we are in native/blocked vm expects stack to be walkable
thread->frame_anchor()->make_walkable(thread);
thread->frame_anchor()->make_walkable();
OrderAccess::storestore(); // Keep thread_state change and make_walkable() separate.
thread->set_thread_state(to);
}

View File

@ -608,7 +608,7 @@ void vm_perform_shutdown_actions() {
JavaThread* jt = JavaThread::cast(thread);
// Must always be walkable or have no last_Java_frame when in
// thread_in_native
jt->frame_anchor()->make_walkable(jt);
jt->frame_anchor()->make_walkable();
jt->set_thread_state(_thread_in_native);
}
}

View File

@ -714,7 +714,7 @@ void SafepointSynchronize::block(JavaThread *thread) {
}
JavaThreadState state = thread->thread_state();
thread->frame_anchor()->make_walkable(thread);
thread->frame_anchor()->make_walkable();
uint64_t safepoint_id = SafepointSynchronize::safepoint_counter();

View File

@ -1584,7 +1584,7 @@ void JavaThread::remove_monitor_chunk(MonitorChunk* chunk) {
void JavaThread::handle_special_runtime_exit_condition() {
if (is_obj_deopt_suspend()) {
frame_anchor()->make_walkable(this);
frame_anchor()->make_walkable();
wait_for_object_deoptimization();
}
JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);)

View File

@ -1424,7 +1424,7 @@ class JavaThread: public Thread {
// Accessing frames
frame last_frame() {
_anchor.make_walkable(this);
_anchor.make_walkable();
return pd_last_frame();
}
javaVFrame* last_java_vframe(RegisterMap* reg_map);