• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "arch/asm_support.h"
17
18.extern InvokeInterpreter
19
20.global DeoptimizeAfterCFrame
21.type DeoptimizeAfterCFrame, %function
22DeoptimizeAfterCFrame:
23    CFI_STARTPROC
24
25    // Parameters:
26    // %rdi - thread
27    // %rsi - pc of the entry
28    // %rdx - pointer to interpreter Frame
29    // %rcx - pointer to cframe origin
30    // %r8  - last restored interpreter Frame
31    // %r9  - callee reg_mask
32    // 8(%rsp) - callee vreg_mask
33
34    // Morph CFrame into C2I bridge frame
35    // FROM         TO
36    //  lr          lr
37    //  fp <----    COMPILED_CODE_TO_INTERPRETER_BRIDGE
38    //  method      fp <----
39
40    CFI_DEF_CFA(rcx, (2 * 8))
41    CFI_REL_OFFSET(rbp, 0)
42    CFI_REL_OFFSET(THREAD_REG, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
43    CFI_REL_OFFSET(r14, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
44    CFI_REL_OFFSET(r13, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
45    CFI_REL_OFFSET(r12, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
46    CFI_REL_OFFSET(rbx, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
47
48    leaq -(((CFRAME_HEADER_SIZE - 2) * 8) + CALLEE_SAVED_SIZE)(%rcx), %rsp
49    // Additional padding to save lr to origin place
50    movq (%rcx), %r12
51    movq %r12, (-8)(%rcx)
52
53    subq $8, %rcx
54    CFI_ADJUST_CFA_OFFSET(8)
55    CFI_REL_OFFSET(rbp, 0)
56
57    movq %rcx, %rbp
58    CFI_DEF_CFA_REGISTER(rbp)
59
60    movq $COMPILED_CODE_TO_INTERPRETER_BRIDGE, (INT_METHOD_OFFSET * 8)(%rcx)
61
62    // Set IFrame's prev_frame to this C2I bridge frame
63    movq %rcx, FRAME_PREV_FRAME_OFFSET(%r8)
64
65    BOUNDARY_FRAME_SLOT = ((CFRAME_HEADER_SIZE - 3) + 1)
66
67    // Copy callee saved registers from cframe into boundary frame.
68    leaq -((CFRAME_CALLEE_REGS_START_SLOT - 1) * 8)(%rcx), %r12
69    leaq -(BOUNDARY_FRAME_SLOT * 8)(%rcx), %r13
70
71    movq (%r12), %rbx
72    movq %rbx, (%r13)
73    CFI_REL_OFFSET(THREAD_REG, -((BOUNDARY_FRAME_SLOT + 0) * 8))
74    movq -8(%r12), %rbx
75    movq %rbx, -8(%r13)
76    CFI_REL_OFFSET(r14, -((BOUNDARY_FRAME_SLOT + 1) * 8))
77    movq -16(%r12), %rbx
78    movq %rbx, -16(%r13)
79    CFI_REL_OFFSET(r13, -((BOUNDARY_FRAME_SLOT + 2) * 8))
80    movq -24(%r12), %rbx
81    movq %rbx, -24(%r13)
82    CFI_REL_OFFSET(r12, -((BOUNDARY_FRAME_SLOT + 3) * 8))
83    movq -32(%r12), %rbx
84    movq %rbx, -32(%r13)
85    CFI_REL_OFFSET(rbx, -((BOUNDARY_FRAME_SLOT + 4) * 8))
86
87    // Save used registers
88    pushq %r8
89    pushq %rcx
90    pushq %rdx
91    pushq %rsi
92    pushq %rdi
93
94    movq %r8, %rcx
95    // Arguments are already lie in the registers, because signature of DeoptimizeAfterCFrame is similar to InvokeInterpreter
96    callq InvokeInterpreter@plt
97    movq %rax, %xmm0
98
99    // Restore used registers
100    popq %rdi
101    popq %rsi
102    popq %rdx
103    popq %rcx
104    popq %r8
105
106    // Restore stack pointer
107    movq %rcx, %rsp
108
109    // Restore callee saved registers
110    subq $(BOUNDARY_FRAME_SLOT * 8), %rcx
111    movq (%rcx), %THREAD_REG
112    movq -8(%rcx), %r14
113    CFI_RESTORE(r14)
114    movq -16(%rcx), %r13
115    CFI_RESTORE(r13)
116    movq -24(%rcx), %r12
117    CFI_RESTORE(r12)
118    movq -32(%rcx), %rbx
119    CFI_RESTORE(rbx)
120
121    // Restore thread register
122    movq %rdi, %THREAD_REG
123    CFI_RESTORE(THREAD_REG)
124
125    popq %rbp
126    CFI_RESTORE(rbp)
127    CFI_DEF_CFA(rsp, (2 * 8))
128    addq $8, %rsp
129    CFI_ADJUST_CFA_OFFSET(-(1 * 8))
130    retq
131    CFI_ENDPROC
132
133.global DeoptimizeAfterIFrame
134.type DeoptimizeAfterIFrame, %function
135DeoptimizeAfterIFrame:
136    CFI_STARTPROC
137
138    // Parameters:
139    // %rdi - thread
140    // %rsi - pc of the entry
141    // %rdx - pointer to interpreter Frame
142    // %rcx - pointer to cframe origin
143    // %r8  - last restored interpreter Frame
144
145    CFI_DEF_CFA(rcx, (2 * 8))
146    CFI_REL_OFFSET(rbp, 0)
147    CFI_REL_OFFSET(r15, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
148    CFI_REL_OFFSET(r14, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
149    CFI_REL_OFFSET(r13, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
150    CFI_REL_OFFSET(r12, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
151    CFI_REL_OFFSET(rbx, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
152
153    movq %rcx, %rbp
154    CFI_DEF_CFA_REGISTER(rbp)
155
156    // Restore stack pointer to the fp pointer of the cframe
157    movq %rcx, %rsp
158
159    // Restore callee saved registers
160    subq $(CFRAME_CALLEE_REGS_START_SLOT * 8), %rcx
161    movq (%rcx), %r15
162    CFI_RESTORE(r15)
163    movq -8(%rcx), %r14
164    CFI_RESTORE(r14)
165    movq -16(%rcx), %r13
166    CFI_RESTORE(r13)
167    movq -24(%rcx), %r12
168    CFI_RESTORE(r12)
169    movq -32(%rcx), %rbx
170    CFI_RESTORE(rbx)
171
172    movq %r8, %rcx
173    callq InvokeInterpreter@plt
174    // InvokeInterpreter returns int64 value, but result can be double, so we copy value to vector register
175    movq %rax, %xmm0
176
177    popq %rbp
178    CFI_RESTORE(rbp)
179    CFI_DEF_CFA(rsp, (1 * 8))
180    retq
181    CFI_ENDPROC
182
183.global DropCompiledFrameAndReturn
184.type DropCompiledFrameAndReturn, %function
185DropCompiledFrameAndReturn:
186    CFI_STARTPROC
187
188    // %rdi - pointer to cframe origin
189
190    CFI_DEF_CFA(rdi, (2 * 8))
191    CFI_REL_OFFSET(rbp, 0)
192    CFI_REL_OFFSET(r15, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
193    CFI_REL_OFFSET(r14, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
194    CFI_REL_OFFSET(r13, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
195    CFI_REL_OFFSET(r12, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
196    CFI_REL_OFFSET(rbx, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
197
198    movq %rdi, %rbp
199    CFI_DEF_CFA_REGISTER(rbp)
200    movq %rdi, %rsp
201
202    // Restore callee saved registers from dropped CFrame
203    subq $(CFRAME_CALLEE_REGS_START_SLOT * 8), %rdi
204    movq (%rdi), %r15
205    CFI_RESTORE(r15)
206    movq -8(%rdi), %r14
207    CFI_RESTORE(r14)
208    movq -16(%rdi), %r13
209    CFI_RESTORE(r13)
210    movq -24(%rdi), %r12
211    CFI_RESTORE(r12)
212    movq -32(%rdi), %rbx
213    CFI_RESTORE(rbx)
214
215    // We need to clear return value, since it will be written to the IFrame's accumulator. Without this, it holds
216    // garbage and StackWalker verification might fail.
217    xorq %rax, %rax
218
219    popq %rbp
220    CFI_RESTORE(rbp)
221    CFI_DEF_CFA(rsp, (1 * 8))
222    retq
223    CFI_ENDPROC
224