Skip to content

Commit 92aa75b

Browse files
committedDec 8, 2021
8274903: Zero: Support AsyncGetCallTrace
Reviewed-by: sspitsyn, aph
1 parent 8345453 commit 92aa75b

File tree

4 files changed

+143
-18
lines changed

4 files changed

+143
-18
lines changed
 

‎src/hotspot/cpu/zero/frame_zero.cpp

+59-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
3+
* Copyright (c) 2007, 2021, Red Hat, Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* 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) {
116116
}
117117

118118
bool frame::safe_for_sender(JavaThread *thread) {
119-
ShouldNotCallThis();
120-
return false;
119+
address sp = (address)_sp;
120+
121+
// consider stack guards when trying to determine "safe" stack pointers
122+
// sp must be within the usable part of the stack (not in guards)
123+
if (!thread->is_in_usable_stack(sp)) {
124+
return false;
125+
}
126+
127+
// an fp must be within the stack and above (but not equal) sp
128+
if (!thread->is_in_stack_range_excl((address)fp(), sp)) {
129+
return false;
130+
}
131+
132+
// All good.
133+
return true;
121134
}
122135

123136
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
124-
ShouldNotCallThis();
125-
return false;
137+
assert(is_interpreted_frame(), "Not an interpreted frame");
138+
// These are reasonable sanity checks
139+
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
140+
return false;
141+
}
142+
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
143+
return false;
144+
}
145+
// These are hacks to keep us out of trouble.
146+
// The problem with these is that they mask other problems
147+
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
148+
return false;
149+
}
150+
151+
// do some validation of frame elements
152+
// first the method
153+
154+
Method* m = *interpreter_frame_method_addr();
155+
156+
// validate the method we'd find in this potential sender
157+
if (!Method::is_valid_method(m)) {
158+
return false;
159+
}
160+
161+
// validate bci/bcp
162+
address bcp = interpreter_frame_bcp();
163+
if (m->validate_bci_from_bcp(bcp) < 0) {
164+
return false;
165+
}
166+
167+
// validate ConstantPoolCache*
168+
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
169+
if (MetaspaceObj::is_valid(cp) == false) {
170+
return false;
171+
}
172+
173+
// validate locals
174+
address locals = (address) *interpreter_frame_locals_addr();
175+
if (!thread->is_in_stack_range_incl(locals, (address)fp())) {
176+
return false;
177+
}
178+
179+
return true;
126180
}
127181

128182
BasicType frame::interpreter_frame_result(oop* oop_result,

‎src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright 2009, 2010 Red Hat, Inc.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2009, 2021, Red Hat, Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -35,3 +35,40 @@ frame JavaThread::pd_last_frame() {
3535
void JavaThread::cache_global_variables() {
3636
// nothing to do
3737
}
38+
39+
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
40+
void* ucontext,
41+
bool isInJava) {
42+
if (has_last_Java_frame()) {
43+
*fr_addr = pd_last_frame();
44+
return true;
45+
}
46+
47+
if (isInJava) {
48+
// We know we are in Java, but there is no frame?
49+
// Try to find the top-most Java frame on Zero stack then.
50+
intptr_t* sp = zero_stack()->sp();
51+
ZeroFrame* zf = top_zero_frame();
52+
while (zf != NULL) {
53+
if (zf->is_interpreter_frame()) {
54+
interpreterState istate = zf->as_interpreter_frame()->interpreter_state();
55+
if (istate->self_link() == istate) {
56+
// Valid interpreter state found, this is our frame.
57+
*fr_addr = frame(zf, sp);
58+
return true;
59+
}
60+
}
61+
sp = ((intptr_t *) zf) + 1;
62+
zf = zf->next();
63+
}
64+
}
65+
66+
// No dice.
67+
return false;
68+
}
69+
70+
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr,
71+
void* ucontext,
72+
bool isInJava) {
73+
return pd_get_top_frame_for_signal_handler(fr_addr, ucontext, isInJava);
74+
}

‎src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
2+
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2007, 2021, Red Hat, Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -96,16 +96,10 @@
9696
public:
9797
bool pd_get_top_frame_for_signal_handler(frame* fr_addr,
9898
void* ucontext,
99-
bool isInJava) {
100-
ShouldNotCallThis();
101-
return false; // silence compile warning
102-
}
99+
bool isInJava);
103100

104101
bool pd_get_top_frame_for_profiling(frame* fr_addr,
105102
void* ucontext,
106-
bool isInJava) {
107-
ShouldNotCallThis();
108-
return false; // silence compile warning
109-
}
103+
bool isInJava);
110104

111105
#endif // OS_CPU_LINUX_ZERO_THREAD_LINUX_ZERO_HPP

‎src/hotspot/share/prims/forte.cpp

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* 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,
314314

315315
frame candidate = *fr;
316316

317+
#ifdef ZERO
318+
// Zero has no frames with code blobs, so the generic code fails.
319+
// Instead, try to do Zero-specific search for Java frame.
320+
321+
{
322+
RegisterMap map(thread, false, false);
323+
324+
while (true) {
325+
// Cannot walk this frame? Cannot do anything anymore.
326+
if (!candidate.safe_for_sender(thread)) {
327+
return false;
328+
}
329+
330+
if (candidate.is_entry_frame()) {
331+
// jcw is NULL if the java call wrapper could not be found
332+
JavaCallWrapper* jcw = candidate.entry_frame_call_wrapper_if_safe(thread);
333+
// If initial frame is frame from StubGenerator and there is no
334+
// previous anchor, there are no java frames associated with a method
335+
if (jcw == NULL || jcw->is_first_frame()) {
336+
return false;
337+
}
338+
}
339+
340+
// If we find a decipherable interpreted frame, this is our initial frame.
341+
if (candidate.is_interpreted_frame()) {
342+
if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {
343+
*initial_frame_p = candidate;
344+
return true;
345+
}
346+
}
347+
348+
// Walk some more.
349+
candidate = candidate.sender(&map);
350+
}
351+
352+
// No dice, report no initial frames.
353+
return false;
354+
}
355+
#endif
356+
317357
// If the starting frame we were given has no codeBlob associated with
318358
// it see if we can find such a frame because only frames with codeBlobs
319359
// are possible Java frames.

0 commit comments

Comments
 (0)
Please sign in to comment.