diff --git a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp index 3bfee914588..69cd56e4f15 100644 --- a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * Copyright (c) 2022, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,6 +27,7 @@ #include "precompiled.hpp" #include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" +#include "runtime/os.inline.hpp" #include "runtime/thread.hpp" frame JavaThread::pd_last_frame() { @@ -54,9 +55,19 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, if (has_last_Java_frame() && frame_anchor()->walkable()) { intptr_t* sp = last_Java_sp(); address pc = _anchor.last_Java_pc(); - // pc can be seen as null because not all writers use store pc + release store sp. - // Simply discard the sample in this very rare case. - if (pc == nullptr) return false; + if (pc == nullptr) { + // This is not uncommon. Many c1/c2 runtime stubs do not set the pc in the anchor. + intptr_t* top_sp = os::Aix::ucontext_get_sp((const ucontext_t*)ucontext); + if ((uint64_t)sp <= ((frame::abi_minframe*)top_sp)->callers_sp) { + // The interrupt occurred either in the last java frame or in its direct callee. + // We cannot be sure that the link register LR was already saved to the + // java frame. Therefore we discard this sample. + return false; + } + // The last java pc will be found in the abi part of the last java frame. + *fr_addr = frame(sp); + return true; + } *fr_addr = frame(sp, pc); return true; } diff --git a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp index bf15786ae1f..06a2a776923 100644 --- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. 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 @@ -53,9 +53,19 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, if (has_last_Java_frame() && frame_anchor()->walkable()) { intptr_t* sp = last_Java_sp(); address pc = _anchor.last_Java_pc(); - // pc can be seen as null because not all writers use store pc + release store sp. - // Simply discard the sample in this very rare case. - if (pc == nullptr) return false; + if (pc == nullptr) { + // This is not uncommon. Many c1/c2 runtime stubs do not set the pc in the anchor. + intptr_t* top_sp = os::Linux::ucontext_get_sp((const ucontext_t*)ucontext); + if ((uint64_t)sp <= ((frame::abi_minframe*)top_sp)->callers_sp) { + // The interrupt occurred either in the last java frame or in its direct callee. + // We cannot be sure that the link register LR was already saved to the + // java frame. Therefore we discard this sample. + return false; + } + // The last java pc will be found in the abi part of the last java frame. + *fr_addr = frame(sp); + return true; + } *fr_addr = frame(sp, pc); return true; }