11/*
2- * Copyright (c) 2003, 2021 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2003, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * Copyright (c) 2015, Red Hat Inc.
44 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
55 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2626
2727package sun .jvm .hotspot .debugger .bsd .aarch64 ;
2828
29+ import sun .jvm .hotspot .code .*;
2930import sun .jvm .hotspot .debugger .*;
3031import sun .jvm .hotspot .debugger .aarch64 .*;
3132import sun .jvm .hotspot .debugger .bsd .*;
3233import sun .jvm .hotspot .debugger .cdbg .*;
3334import sun .jvm .hotspot .debugger .cdbg .basic .*;
35+ import sun .jvm .hotspot .runtime .*;
36+ import sun .jvm .hotspot .runtime .aarch64 .*;
3437
3538public final class BsdAARCH64CFrame extends BasicCFrame {
36- public BsdAARCH64CFrame (BsdDebugger dbg , Address fp , Address pc ) {
39+ public BsdAARCH64CFrame (BsdDebugger dbg , Address sp , Address fp , Address pc ) {
3740 super (dbg .getCDebugger ());
41+ this .sp = sp ;
3842 this .fp = fp ;
3943 this .pc = pc ;
4044 this .dbg = dbg ;
@@ -54,28 +58,65 @@ public Address localVariableBase() {
5458 return fp ;
5559 }
5660
61+ @ Override
5762 public CFrame sender (ThreadProxy thread ) {
58- AARCH64ThreadContext context = ( AARCH64ThreadContext ) thread . getContext ( );
59- Address rsp = context . getRegisterAsAddress ( AARCH64ThreadContext . SP );
63+ return sender ( thread , null , null , null );
64+ }
6065
61- if ((fp == null ) || fp .lessThan (rsp )) {
62- return null ;
66+ @ Override
67+ public CFrame sender (ThreadProxy thread , Address nextSP , Address nextFP , Address nextPC ) {
68+ // Check fp
69+ // Skip if both nextFP and nextPC are given - do not need to load from fp.
70+ if (nextFP == null && nextPC == null ) {
71+ if (fp == null ) {
72+ return null ;
73+ }
74+
75+ // Check alignment of fp
76+ if (dbg .getAddressValue (fp ) % (2 * ADDRESS_SIZE ) != 0 ) {
77+ return null ;
78+ }
6379 }
6480
65- // Check alignment of fp
66- if (dbg .getAddressValue (fp ) % (2 * ADDRESS_SIZE ) != 0 ) {
81+ if (nextFP == null ) {
82+ nextFP = fp .getAddressAt (0 );
83+ }
84+ if (nextFP == null ) {
6785 return null ;
6886 }
6987
70- Address nextFP = fp .getAddressAt (0 * ADDRESS_SIZE );
71- if (nextFP == null || nextFP .lessThanOrEqual (fp )) {
72- return null ;
88+ if (nextPC == null ) {
89+ nextPC = fp .getAddressAt (ADDRESS_SIZE );
7390 }
74- Address nextPC = fp .getAddressAt (1 * ADDRESS_SIZE );
7591 if (nextPC == null ) {
7692 return null ;
7793 }
78- return new BsdAARCH64CFrame (dbg , nextFP , nextPC );
94+
95+ if (nextSP == null ) {
96+ CodeCache cc = VM .getVM ().getCodeCache ();
97+ CodeBlob currentBlob = cc .findBlobUnsafe (pc ());
98+
99+ // This case is different from HotSpot. See JDK-8371194 for details.
100+ if (currentBlob != null && (currentBlob .isContinuationStub () || currentBlob .isNativeMethod ())) {
101+ // Use FP since it should always be valid for these cases.
102+ // TODO: These should be walked as Frames not CFrames.
103+ nextSP = fp .addOffsetTo (2 * ADDRESS_SIZE );
104+ } else {
105+ CodeBlob codeBlob = cc .findBlobUnsafe (nextPC );
106+ boolean useCodeBlob = codeBlob != null && codeBlob .getFrameSize () > 0 ;
107+ nextSP = useCodeBlob ? nextFP .addOffsetTo ((2 * ADDRESS_SIZE ) - codeBlob .getFrameSize ()) : nextFP ;
108+ }
109+ }
110+ if (nextSP == null ) {
111+ return null ;
112+ }
113+
114+ return new BsdAARCH64CFrame (dbg , nextSP , nextFP , nextPC );
115+ }
116+
117+ @ Override
118+ public Frame toFrame () {
119+ return new AARCH64Frame (sp , fp , pc );
79120 }
80121
81122 // package/class internals only
0 commit comments