From e3c3a54f7aad85790417093273a61d775d2ed539 Mon Sep 17 00:00:00 2001
From: Chris Plummer <cjplummer@openjdk.org>
Date: Mon, 15 Aug 2016 13:14:08 -0700
Subject: [PATCH] 8133740: NMT for Linux/x86/x64 and bsd/x64 slowdebug builds
 includes NativeCallStack::NativeCallStack() frame in backtrace

Skip an extra frame in _get_previous_fp() when it is not inlined.

Reviewed-by: dholmes, zgu
---
 hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp         | 10 +++++++++-
 hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp     | 10 +++++++++-
 hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp |  8 ++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index 5f7d479726c..0bdbc7c3aaa 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -417,7 +417,15 @@ intptr_t* _get_previous_fp() {
 #else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
 #endif
-  return (intptr_t*) *ebp;   // we want what it points to.
+  // ebp is for this frame (_get_previous_fp). We want the ebp for the
+  // caller of os::current_frame*(), so go up two frames. However, for
+  // optimized builds, _get_previous_fp() will be inlined, so only go
+  // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+  return **(intptr_t***)ebp;
+#else
+  return *ebp;
+#endif
 }
 
 
diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index 06a8a6eb5f1..6eeb1280c82 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -235,7 +235,15 @@ intptr_t* _get_previous_fp() {
 #else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
 #endif
-  return (intptr_t*) *ebp;   // we want what it points to.
+  // ebp is for this frame (_get_previous_fp). We want the ebp for the
+  // caller of os::current_frame*(), so go up two frames. However, for
+  // optimized builds, _get_previous_fp() will be inlined, so only go
+  // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+  return **(intptr_t***)ebp;
+#else
+  return *ebp;
+#endif
 }
 
 
diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
index efb1b3b0851..f3df7d386d6 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -496,7 +496,15 @@ intptr_t* _get_previous_fp() {
   __asm {
     mov frameptr, ebp
   };
+  // ebp (frameptr) is for this frame (_get_previous_fp). We want the ebp for the
+  // caller of os::current_frame*(), so go up two frames. However, for
+  // optimized builds, _get_previous_fp() will be inlined, so only go
+  // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+  return **(intptr_t***)frameptr;
+#else
   return *frameptr;
+#endif
 }
 #endif // !AMD64