Skip to content

Commit 9048045

Browse files
dave-griffithsJini George
authored andcommitted
8214226: Incorrect BCI and Line Number with jstack if the top frame is in the interpreter
Read in the bcp from r13 for the top level interpreter frames Reviewed-by: jcbeyler, jgeorge
1 parent a438a07 commit 9048045

2 files changed

Lines changed: 43 additions & 21 deletions

File tree

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2018, 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
@@ -97,6 +97,10 @@ public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
9797
}
9898
if (guesser.getPC() == null) {
9999
return new X86Frame(guesser.getSP(), guesser.getFP());
100+
} else if (VM.getVM().getInterpreter().contains(guesser.getPC())) {
101+
// pass the value of R13 which contains the bcp for the top level frame
102+
Address bcp = context.getRegisterAsAddress(AMD64ThreadContext.R13);
103+
return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC(), null, bcp);
100104
} else {
101105
return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
102106
}

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2001, 2018, 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
@@ -95,6 +95,7 @@ private static synchronized void initialize(TypeDataBase db) {
9595
// an additional field beyond sp and pc:
9696
Address raw_fp; // frame pointer
9797
private Address raw_unextendedSP;
98+
private Address live_bcp;
9899

99100
private X86Frame() {
100101
}
@@ -117,15 +118,29 @@ private void adjustForDeopt() {
117118
}
118119
}
119120

120-
public X86Frame(Address raw_sp, Address raw_fp, Address pc) {
121+
private void initFrame(Address raw_sp, Address raw_fp, Address pc, Address raw_unextendedSp, Address live_bcp) {
121122
this.raw_sp = raw_sp;
122-
this.raw_unextendedSP = raw_sp;
123123
this.raw_fp = raw_fp;
124-
this.pc = pc;
124+
if (raw_unextendedSp == null) {
125+
this.raw_unextendedSP = raw_sp;
126+
} else {
127+
this.raw_unextendedSP = raw_unextendedSp;
128+
}
129+
if (pc == null) {
130+
this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
131+
} else {
132+
this.pc = pc;
133+
}
134+
this.live_bcp = live_bcp;
125135
adjustUnextendedSP();
126136

127137
// Frame must be fully constructed before this call
128138
adjustForDeopt();
139+
}
140+
141+
142+
public X86Frame(Address raw_sp, Address raw_fp, Address pc) {
143+
initFrame(raw_sp, raw_fp, pc, null, null);
129144

130145
if (DEBUG) {
131146
System.out.println("X86Frame(sp, fp, pc): " + this);
@@ -134,14 +149,7 @@ public X86Frame(Address raw_sp, Address raw_fp, Address pc) {
134149
}
135150

136151
public X86Frame(Address raw_sp, Address raw_fp) {
137-
this.raw_sp = raw_sp;
138-
this.raw_unextendedSP = raw_sp;
139-
this.raw_fp = raw_fp;
140-
this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
141-
adjustUnextendedSP();
142-
143-
// Frame must be fully constructed before this call
144-
adjustForDeopt();
152+
initFrame(raw_sp, raw_fp, null, null, null);
145153

146154
if (DEBUG) {
147155
System.out.println("X86Frame(sp, fp): " + this);
@@ -150,20 +158,21 @@ public X86Frame(Address raw_sp, Address raw_fp) {
150158
}
151159

152160
public X86Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
153-
this.raw_sp = raw_sp;
154-
this.raw_unextendedSP = raw_unextendedSp;
155-
this.raw_fp = raw_fp;
156-
this.pc = pc;
157-
adjustUnextendedSP();
158-
159-
// Frame must be fully constructed before this call
160-
adjustForDeopt();
161+
initFrame(raw_sp, raw_fp, pc, raw_unextendedSp, null);
161162

162163
if (DEBUG) {
163164
System.out.println("X86Frame(sp, unextendedSP, fp, pc): " + this);
164165
dumpStack();
165166
}
167+
}
166168

169+
public X86Frame(Address raw_sp, Address raw_fp, Address pc, Address raw_unextendedSp, Address live_bcp) {
170+
initFrame(raw_sp, raw_fp, pc, raw_unextendedSp, live_bcp);
171+
172+
if (DEBUG) {
173+
System.out.println("X86Frame(sp, fp, pc, unextendedSP, live_bcp): " + this);
174+
dumpStack();
175+
}
167176
}
168177

169178
public Object clone() {
@@ -173,6 +182,7 @@ public Object clone() {
173182
frame.raw_fp = raw_fp;
174183
frame.pc = pc;
175184
frame.deoptimized = deoptimized;
185+
frame.live_bcp = live_bcp;
176186
return frame;
177187
}
178188

@@ -433,6 +443,14 @@ public int getInterpreterFrameBCI() {
433443
// for use in a non-debugging, or reflective, system. Need to
434444
// figure out how to express this.
435445
Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
446+
447+
// If we are in the top level frame then the bcp may have been set for us. If so then let it
448+
// take priority. If we are in a top level interpreter frame, the bcp is live in R13 (on x86)
449+
// and not saved in the BCX stack slot.
450+
if (live_bcp != null) {
451+
bcp = live_bcp;
452+
}
453+
436454
Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
437455
Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
438456
return bcpToBci(bcp, method);

0 commit comments

Comments
 (0)