• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2024 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#include "arch/amd64/helpers_amd64.S"
18
19// Frame* CreateFrameForMethodWithActualArgsDyn(uint32_t num_actual_args, Method* method, Frame* prev);
20.extern CreateFrameForMethodWithActualArgsDyn
21// void InterpreterEntryPoint(Method* pc, Frame* frame, bool is_dynamic);
22.extern InterpreterEntryPoint
23// void FreeFrame(Frame* frame);
24.extern FreeFrame
25// bool DecrementHotnessCounterDyn(Method* method, TaggedValue func_obj);
26.extern DecrementHotnessCounterDyn
27
28// CompiledCodeToInterpreterBridgeDyn, follows DynamicMethod calling convention
29.global CompiledCodeToInterpreterBridgeDyn
30TYPE_FUNCTION(CompiledCodeToInterpreterBridgeDyn)
31CompiledCodeToInterpreterBridgeDyn:
32    CFI_STARTPROC
33    CFI_DEF_CFA(rsp, 8)
34
35    // method:      %rdi
36    // num_args:    %rsi
37    // arg_i:       24(%rbp, i, 8)
38
39    // Save return address to the TLS field
40    movq (%rsp), %rax
41    movq %rax, MANAGED_THREAD_NATIVE_PC_OFFSET(%THREAD_REG)
42
43    pushq $COMPILED_CODE_TO_INTERPRETER_BRIDGE
44    CFI_ADJUST_CFA_OFFSET(8)
45
46    // construct the frame
47    pushq %rbp
48    CFI_ADJUST_CFA_OFFSET(8)
49    CFI_REL_OFFSET(rbp, 0)
50    movq %rsp, %rbp // set frame pointer
51    CFI_DEF_CFA_REGISTER(rbp)
52
53    subq $8, %rsp
54
55    // save all the callee saved registers to the stack
56    // stack walker will read them during stack unwinding
57    pushq %r15
58    CFI_REL_OFFSET(r15, -(2 * 8))
59    pushq %r14
60    CFI_REL_OFFSET(r14, -(3 * 8))
61    pushq %r13
62    CFI_REL_OFFSET(r13, -(4 * 8))
63    pushq %r12
64    CFI_REL_OFFSET(r12, -(5 * 8))
65    pushq %rbx
66    CFI_REL_OFFSET(rbx, -(6 * 8))
67
68    subq $8, %rsp
69
70    // Before we call DecrementHotnessCounterDyn we should set pointer to C2I frame in the TLS,
71    // because compilation may fall into safepoint, so we need to make caller's callee registers
72    // visible for the stack walker.
73    movq %rbp, MANAGED_THREAD_FRAME_OFFSET(%THREAD_REG)
74
75    PUSH_GENERAL_REGS
76    // Pass this function as second arg
77    movq 24(%rbp), %rsi
78    movq %THREAD_REG, %rdx
79    callq DecrementHotnessCounterDyn@plt
80    cmpb $0, %al
81    je .Lnot_compiled
82
83    // Compilation successfully done, so recover caller's frame in the TLS, since C2I is not needed.
84    movq (%rbp), %r8
85    movq %r8, MANAGED_THREAD_FRAME_OFFSET(%THREAD_REG)
86
87    POP_GENERAL_REGS
88
89    movq %rbp, %rsp
90    addq $16, %rsp
91    movq (%rbp), %rbp
92    CFI_REMEMBER_STATE
93    CFI_RESTORE(rbp)
94    CFI_DEF_CFA(rsp, 8)
95
96    movq METHOD_COMPILED_ENTRY_POINT_OFFSET(%rdi), %rax
97    jmp *%rax
98    CFI_RESTORE_STATE
99    CFI_DEF_CFA(rbp, (3 * 8))
100
101.Lnot_compiled:
102    RELOAD_GENERAL_REGS
103
104    // Create an interpreter frame
105    // %r12         - iframe*
106    xchgq %rsi, %rdi
107    movq %rbp, %rdx
108    // Frame* CreateFrameForMethodWithActualArgsDyn(uint32_t num_actual_args, Method* method, Frame* prev);
109    callq CreateFrameForMethodWithActualArgsDyn@plt
110    movq %rax, %r12
111
112    POP_GENERAL_REGS
113
114    // setup regs as follows
115    // %r12         - iframe*
116    // %rdi         - method*
117    // %rsi         - num_actual_args
118
119    // %r15d        - num_iframe_args = max(num_actual_args, mehtod->num_args_)
120    // %rax         - iframe.vregs_ + num_vregs_
121    movl METHOD_NUM_ARGS_OFFSET(%rdi), %r15d
122    cmpl %r15d, %esi
123    cmovge %esi, %r15d
124    movl FRAME_NUM_VREGS_OFFSET(%r12), %eax
125    subl %r15d, %eax
126    leaq FRAME_VREGS_OFFSET(%r12, %rax, FRAME_VREGISTER_SIZE), %rax
127
128    test %rsi, %rsi
129    jz .Linit_rest
130
131    // copy actual args
132    // %rdx         - incoming stack arguments
133    leaq 24(%rbp), %rdx
134    leal -FRAME_VREGISTER_SIZE(, %esi, FRAME_VREGISTER_SIZE), %r14d
135.Lloop_actual:
136    movq (%rdx, %r14), %rcx
137    movq %rcx, (%rax, %r14)
138    subl $FRAME_VREGISTER_SIZE, %r14d
139    jae .Lloop_actual
140
141.Linit_rest:
142    // r15d         - num_rest_args = num_iframe_args - num_actual_args
143    subl %esi, %r15d
144    jz .Lcall_interpreter
145
146    // init rest args
147    // %r14         - iframe.vregs_ + num_vregs_ + num_actual_args
148    // %rax         - initial tagged value (TAGGED_VALUE_UNDEFINED)
149    leaq (%rax, %rsi, FRAME_VREGISTER_SIZE), %r14
150    movq $TAGGED_VALUE_UNDEFINED, %rax
151    leal -FRAME_VREGISTER_SIZE(, %r15d, FRAME_VREGISTER_SIZE), %r15d
152.Lloop_rest:
153    movq %rax, (%r14, %r15)
154    subl $FRAME_VREGISTER_SIZE, %r15d
155    jae .Lloop_rest
156
157.Lcall_interpreter:
158#if defined(PANDA_WITH_ECMASCRIPT) && defined(ARK_INTRINSIC_SET)
159    // Setup EcmascriptEnvironment
160    // %r14       - this func (1st arg)
161    // %rax       - iframe ext data
162    movq 24(%rbp), %r14
163
164    leaq (EXTFRAME_EXT_DATA_OFFSET-EXTFRAME_FRAME_OFFSET)(%r12), %rax
165
166    // Store constant pool to iframe
167    movq JSFUNCTION_CONSTANT_POOL_OFFSET(%r14), %r15
168    movq %r15, ECMASCRIPT_ENVIRONMENT_CONSTANT_POOL_OFFSET(%rax)
169
170    // Store lexical env to iframe
171    movq JSFUNCTION_LEXICAL_ENV_OFFSET(%r14), %r15
172    movq %r15, ECMASCRIPT_ENVIRONMENT_LEXICAL_ENV_OFFSET(%rax)
173
174    // Store this func to iframe
175    movq %r14, ECMASCRIPT_ENVIRONMENT_THIS_FUNC_OFFSET(%rax)
176#endif
177
178    // call InterpreterEntryPoint
179    movq %r12, %rsi
180    // void InterpreterEntryPoint(Method *method, Frame* frame);
181    callq InterpreterEntryPoint@plt
182
183    // handle the result
184    // setup regs as follows
185    // %r12         - iframe*
186    // %r13/%r14    - result
187    leaq FRAME_ACC_OFFSET(%r12), %rax
188    movq (%rax), %r13
189    movq FRAME_ACC_MIRROR_OFFSET(%rax), %r14
190
191    movq %r12, %rdi
192    // void FreeFrame(Frame* frame);
193    callq FreeFrame@plt
194
195    movq %r13, %rax
196    movq %r14, %rdx
197
198    leaq -48(%rbp), %rsp
199    popq %rbx
200    CFI_RESTORE(rbx)
201    popq %r12
202    CFI_RESTORE(r12)
203    popq %r13
204    CFI_RESTORE(r13)
205    popq %r14
206    CFI_RESTORE(r14)
207    popq %r15
208    CFI_RESTORE(r15)
209    addq $8, %rsp
210
211    popq %rbp
212    CFI_RESTORE(rbp)
213    CFI_DEF_CFA(rsp, (2 * 8))
214    addq $8, %rsp
215    CFI_ADJUST_CFA_OFFSET(-(1 * 8))
216    retq
217    CFI_ENDPROC
218