8214226: Incorrect BCI and Line Number with jstack if the top frame is in the interpreter
authorjgeorge
Thu, 13 Dec 2018 15:11:25 +0530
changeset 53008 9a73a4e4011f
parent 53007 e2798bf6318a
child 53009 c45615dc6bfc
8214226: Incorrect BCI and Line Number with jstack if the top frame is in the interpreter Summary: Read in the bcp from r13 for the top level interpreter frames Reviewed-by: jcbeyler, jgeorge Contributed-by: david.griffiths@gmail.com
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Thu Dec 13 17:28:30 2018 +0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Thu Dec 13 15:11:25 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -97,6 +97,10 @@
     }
     if (guesser.getPC() == null) {
       return new X86Frame(guesser.getSP(), guesser.getFP());
+    } else if (VM.getVM().getInterpreter().contains(guesser.getPC())) {
+      // pass the value of R13 which contains the bcp for the top level frame
+      Address bcp = context.getRegisterAsAddress(AMD64ThreadContext.R13);
+      return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC(), null, bcp);
     } else {
       return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
     }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Thu Dec 13 17:28:30 2018 +0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Thu Dec 13 15:11:25 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -95,6 +95,7 @@
   // an additional field beyond sp and pc:
   Address raw_fp; // frame pointer
   private Address raw_unextendedSP;
+  private Address live_bcp;
 
   private X86Frame() {
   }
@@ -117,15 +118,29 @@
     }
   }
 
-  public X86Frame(Address raw_sp, Address raw_fp, Address pc) {
+  private void initFrame(Address raw_sp, Address raw_fp, Address pc, Address raw_unextendedSp, Address live_bcp) {
     this.raw_sp = raw_sp;
-    this.raw_unextendedSP = raw_sp;
     this.raw_fp = raw_fp;
-    this.pc = pc;
+    if (raw_unextendedSp == null) {
+        this.raw_unextendedSP = raw_sp;
+    } else {
+        this.raw_unextendedSP = raw_unextendedSp;
+    }
+    if (pc == null) {
+        this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
+    } else {
+        this.pc = pc;
+    }
+    this.live_bcp = live_bcp;
     adjustUnextendedSP();
 
     // Frame must be fully constructed before this call
     adjustForDeopt();
+}
+
+
+  public X86Frame(Address raw_sp, Address raw_fp, Address pc) {
+    initFrame(raw_sp, raw_fp, pc, null, null);
 
     if (DEBUG) {
       System.out.println("X86Frame(sp, fp, pc): " + this);
@@ -134,14 +149,7 @@
   }
 
   public X86Frame(Address raw_sp, Address raw_fp) {
-    this.raw_sp = raw_sp;
-    this.raw_unextendedSP = raw_sp;
-    this.raw_fp = raw_fp;
-    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
-    adjustUnextendedSP();
-
-    // Frame must be fully constructed before this call
-    adjustForDeopt();
+    initFrame(raw_sp, raw_fp, null, null, null);
 
     if (DEBUG) {
       System.out.println("X86Frame(sp, fp): " + this);
@@ -150,20 +158,21 @@
   }
 
   public X86Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
-    this.raw_sp = raw_sp;
-    this.raw_unextendedSP = raw_unextendedSp;
-    this.raw_fp = raw_fp;
-    this.pc = pc;
-    adjustUnextendedSP();
-
-    // Frame must be fully constructed before this call
-    adjustForDeopt();
+    initFrame(raw_sp, raw_fp, pc, raw_unextendedSp, null);
 
     if (DEBUG) {
       System.out.println("X86Frame(sp, unextendedSP, fp, pc): " + this);
       dumpStack();
     }
+  }
 
+  public X86Frame(Address raw_sp, Address raw_fp, Address pc, Address raw_unextendedSp, Address live_bcp) {
+    initFrame(raw_sp, raw_fp, pc, raw_unextendedSp, live_bcp);
+
+    if (DEBUG) {
+      System.out.println("X86Frame(sp, fp, pc, unextendedSP, live_bcp): " + this);
+      dumpStack();
+    }
   }
 
   public Object clone() {
@@ -173,6 +182,7 @@
     frame.raw_fp = raw_fp;
     frame.pc = pc;
     frame.deoptimized = deoptimized;
+    frame.live_bcp = live_bcp;
     return frame;
   }
 
@@ -433,6 +443,14 @@
     // for use in a non-debugging, or reflective, system. Need to
     // figure out how to express this.
     Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
+
+    // If we are in the top level frame then the bcp  may have been set for us. If so then let it
+    // take priority. If we are in a top level interpreter frame, the bcp is live in R13 (on x86)
+    // and not saved in the BCX stack slot.
+    if (live_bcp != null) {
+        bcp = live_bcp;
+    }
+
     Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
     Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
     return bcpToBci(bcp, method);