8274903: Zero: Support AsyncGetCallTrace
Reviewed-by: sspitsyn, aph
This commit is contained in:
parent
83454530ea
commit
92aa75b721
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||
* Copyright (c) 2007, 2021, Red Hat, Inc. 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
|
||||
@ -116,13 +116,67 @@ void frame::patch_pc(Thread* thread, address pc) {
|
||||
}
|
||||
|
||||
bool frame::safe_for_sender(JavaThread *thread) {
|
||||
ShouldNotCallThis();
|
||||
return false;
|
||||
address sp = (address)_sp;
|
||||
|
||||
// consider stack guards when trying to determine "safe" stack pointers
|
||||
// sp must be within the usable part of the stack (not in guards)
|
||||
if (!thread->is_in_usable_stack(sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// an fp must be within the stack and above (but not equal) sp
|
||||
if (!thread->is_in_stack_range_excl((address)fp(), sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All good.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
|
||||
ShouldNotCallThis();
|
||||
return false;
|
||||
assert(is_interpreted_frame(), "Not an interpreted frame");
|
||||
// These are reasonable sanity checks
|
||||
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
// These are hacks to keep us out of trouble.
|
||||
// The problem with these is that they mask other problems
|
||||
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
|
||||
return false;
|
||||
}
|
||||
|
||||
// do some validation of frame elements
|
||||
// first the method
|
||||
|
||||
Method* m = *interpreter_frame_method_addr();
|
||||
|
||||
// validate the method we'd find in this potential sender
|
||||
if (!Method::is_valid_method(m)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate bci/bcp
|
||||
address bcp = interpreter_frame_bcp();
|
||||
if (m->validate_bci_from_bcp(bcp) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate ConstantPoolCache*
|
||||
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
|
||||
if (MetaspaceObj::is_valid(cp) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate locals
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
if (!thread->is_in_stack_range_incl(locals, (address)fp())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009, 2010 Red Hat, Inc.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2021, Red Hat, Inc. 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
|
||||
@ -35,3 +35,40 @@ frame JavaThread::pd_last_frame() {
|
||||
void JavaThread::cache_global_variables() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext,
|
||||
bool isInJava) {
|
||||
if (has_last_Java_frame()) {
|
||||
*fr_addr = pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isInJava) {
|
||||
// We know we are in Java, but there is no frame?
|
||||
// Try to find the top-most Java frame on Zero stack then.
|
||||
intptr_t* sp = zero_stack()->sp();
|
||||
ZeroFrame* zf = top_zero_frame();
|
||||
while (zf != NULL) {
|
||||
if (zf->is_interpreter_frame()) {
|
||||
interpreterState istate = zf->as_interpreter_frame()->interpreter_state();
|
||||
if (istate->self_link() == istate) {
|
||||
// Valid interpreter state found, this is our frame.
|
||||
*fr_addr = frame(zf, sp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
sp = ((intptr_t *) zf) + 1;
|
||||
zf = zf->next();
|
||||
}
|
||||
}
|
||||
|
||||
// No dice.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr,
|
||||
void* ucontext,
|
||||
bool isInJava) {
|
||||
return pd_get_top_frame_for_signal_handler(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2021, Red Hat, Inc. 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
|
||||
@ -96,16 +96,10 @@
|
||||
public:
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext,
|
||||
bool isInJava) {
|
||||
ShouldNotCallThis();
|
||||
return false; // silence compile warning
|
||||
}
|
||||
bool isInJava);
|
||||
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr,
|
||||
void* ucontext,
|
||||
bool isInJava) {
|
||||
ShouldNotCallThis();
|
||||
return false; // silence compile warning
|
||||
}
|
||||
bool isInJava);
|
||||
|
||||
#endif // OS_CPU_LINUX_ZERO_THREAD_LINUX_ZERO_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -314,6 +314,46 @@ static bool find_initial_Java_frame(JavaThread* thread,
|
||||
|
||||
frame candidate = *fr;
|
||||
|
||||
#ifdef ZERO
|
||||
// Zero has no frames with code blobs, so the generic code fails.
|
||||
// Instead, try to do Zero-specific search for Java frame.
|
||||
|
||||
{
|
||||
RegisterMap map(thread, false, false);
|
||||
|
||||
while (true) {
|
||||
// Cannot walk this frame? Cannot do anything anymore.
|
||||
if (!candidate.safe_for_sender(thread)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (candidate.is_entry_frame()) {
|
||||
// jcw is NULL if the java call wrapper could not be found
|
||||
JavaCallWrapper* jcw = candidate.entry_frame_call_wrapper_if_safe(thread);
|
||||
// If initial frame is frame from StubGenerator and there is no
|
||||
// previous anchor, there are no java frames associated with a method
|
||||
if (jcw == NULL || jcw->is_first_frame()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we find a decipherable interpreted frame, this is our initial frame.
|
||||
if (candidate.is_interpreted_frame()) {
|
||||
if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {
|
||||
*initial_frame_p = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Walk some more.
|
||||
candidate = candidate.sender(&map);
|
||||
}
|
||||
|
||||
// No dice, report no initial frames.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the starting frame we were given has no codeBlob associated with
|
||||
// it see if we can find such a frame because only frames with codeBlobs
|
||||
// are possible Java frames.
|
||||
|
Loading…
x
Reference in New Issue
Block a user