blob: 388fc8db746e151134446dc4c467852ec1811454 [file] [log] [blame]
Bill Buzbee3b0b4b92016-02-02 13:45:36 +00001/*
2 * ===========================================================================
3 * Common subroutines and data
4 * ===========================================================================
5 */
6
7
8/*
9 * We've detected a condition that will result in an exception, but the exception
10 * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
11 * TUNING: for consistency, we may want to just go ahead and handle these here.
12 */
Bill Buzbee3b0b4b92016-02-02 13:45:36 +000013common_errDivideByZero:
14 EXPORT_PC
15#if MTERP_LOGGING
16 mov x0, xSELF
17 add x1, xFP, #OFF_FP_SHADOWFRAME
18 bl MterpLogDivideByZeroException
19#endif
20 b MterpCommonFallback
21
22common_errArrayIndex:
23 EXPORT_PC
24#if MTERP_LOGGING
25 mov x0, xSELF
26 add x1, xFP, #OFF_FP_SHADOWFRAME
27 bl MterpLogArrayIndexException
28#endif
29 b MterpCommonFallback
30
31common_errNegativeArraySize:
32 EXPORT_PC
33#if MTERP_LOGGING
34 mov x0, xSELF
35 add x1, xFP, #OFF_FP_SHADOWFRAME
36 bl MterpLogNegativeArraySizeException
37#endif
38 b MterpCommonFallback
39
40common_errNoSuchMethod:
41 EXPORT_PC
42#if MTERP_LOGGING
43 mov x0, xSELF
44 add x1, xFP, #OFF_FP_SHADOWFRAME
45 bl MterpLogNoSuchMethodException
46#endif
47 b MterpCommonFallback
48
49common_errNullObject:
50 EXPORT_PC
51#if MTERP_LOGGING
52 mov x0, xSELF
53 add x1, xFP, #OFF_FP_SHADOWFRAME
54 bl MterpLogNullObjectException
55#endif
56 b MterpCommonFallback
57
58common_exceptionThrown:
59 EXPORT_PC
60#if MTERP_LOGGING
61 mov x0, xSELF
62 add x1, xFP, #OFF_FP_SHADOWFRAME
63 bl MterpLogExceptionThrownException
64#endif
65 b MterpCommonFallback
66
67MterpSuspendFallback:
68 EXPORT_PC
69#if MTERP_LOGGING
70 mov x0, xSELF
71 add x1, xFP, #OFF_FP_SHADOWFRAME
72 ldr x2, [xSELF, #THREAD_FLAGS_OFFSET]
73 bl MterpLogSuspendFallback
74#endif
75 b MterpCommonFallback
76
77/*
78 * If we're here, something is out of the ordinary. If there is a pending
79 * exception, handle it. Otherwise, roll back and retry with the reference
80 * interpreter.
81 */
82MterpPossibleException:
83 ldr x0, [xSELF, #THREAD_EXCEPTION_OFFSET]
84 cbz x0, MterpFallback // If not, fall back to reference interpreter.
85 /* intentional fallthrough - handle pending exception. */
86/*
87 * On return from a runtime helper routine, we've found a pending exception.
88 * Can we handle it here - or need to bail out to caller?
89 *
90 */
91MterpException:
92 mov x0, xSELF
93 add x1, xFP, #OFF_FP_SHADOWFRAME
94 bl MterpHandleException // (self, shadow_frame)
95 cbz w0, MterpExceptionReturn // no local catch, back to caller.
96 ldr x0, [xFP, #OFF_FP_CODE_ITEM]
97 ldr w1, [xFP, #OFF_FP_DEX_PC]
98 ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
99 add xPC, x0, #CODEITEM_INSNS_OFFSET
100 add xPC, xPC, x1, lsl #1 // generate new dex_pc_ptr
Bill Buzbeefd522f92016-02-11 22:37:42 +0000101 /* Do we need to switch interpreters? */
102 bl MterpShouldSwitchInterpreters
103 cbnz w0, MterpFallback
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000104 /* resume execution at catch block */
Bill Buzbeefd522f92016-02-11 22:37:42 +0000105 EXPORT_PC
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000106 FETCH_INST
107 GET_INST_OPCODE ip
108 GOTO_OPCODE ip
109 /* NOTE: no fallthrough */
Bill Buzbee1d011d92016-04-04 16:59:29 +0000110/*
111 * Common handling for branches with support for Jit profiling.
112 * On entry:
113 * wINST <= signed offset
114 * wPROFILE <= signed hotness countdown (expanded to 32 bits)
115 * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
116 *
117 * We have quite a few different cases for branch profiling, OSR detection and
118 * suspend check support here.
119 *
120 * Taken backward branches:
121 * If profiling active, do hotness countdown and report if we hit zero.
122 * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
123 * Is there a pending suspend request? If so, suspend.
124 *
125 * Taken forward branches and not-taken backward branches:
126 * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
127 *
128 * Our most common case is expected to be a taken backward branch with active jit profiling,
129 * but no full OSR check and no pending suspend request.
130 * Next most common case is not-taken branch with no full OSR check.
131 *
132 */
133MterpCommonTakenBranchNoFlags:
134 cmp wINST, #0
135 b.gt .L_forward_branch // don't add forward branches to hotness
136 tbnz wPROFILE, #31, .L_no_count_backwards // go if negative
137 subs wPROFILE, wPROFILE, #1 // countdown
138 b.eq .L_add_batch // counted down to zero - report
139.L_resume_backward_branch:
140 ldr lr, [xSELF, #THREAD_FLAGS_OFFSET]
141 add w2, wINST, wINST // w2<- byte offset
142 FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
143 REFRESH_IBASE
Hiroshi Yamauchi30493242016-11-03 13:06:52 -0700144 ands lr, lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
Bill Buzbee1d011d92016-04-04 16:59:29 +0000145 b.ne .L_suspend_request_pending
146 GET_INST_OPCODE ip // extract opcode from wINST
147 GOTO_OPCODE ip // jump to next instruction
148
149.L_suspend_request_pending:
150 EXPORT_PC
151 mov x0, xSELF
152 bl MterpSuspendCheck // (self)
153 cbnz x0, MterpFallback
154 REFRESH_IBASE // might have changed during suspend
155 GET_INST_OPCODE ip // extract opcode from wINST
156 GOTO_OPCODE ip // jump to next instruction
157
158.L_no_count_backwards:
159 cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
160 b.ne .L_resume_backward_branch
161 mov x0, xSELF
162 add x1, xFP, #OFF_FP_SHADOWFRAME
163 mov x2, xINST
164 EXPORT_PC
165 bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
166 cbnz x0, MterpOnStackReplacement
167 b .L_resume_backward_branch
168
169.L_forward_branch:
170 cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
171 b.eq .L_check_osr_forward
172.L_resume_forward_branch:
173 add w2, wINST, wINST // w2<- byte offset
174 FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
175 GET_INST_OPCODE ip // extract opcode from wINST
176 GOTO_OPCODE ip // jump to next instruction
177
178.L_check_osr_forward:
179 mov x0, xSELF
180 add x1, xFP, #OFF_FP_SHADOWFRAME
181 mov x2, xINST
182 EXPORT_PC
183 bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
184 cbnz x0, MterpOnStackReplacement
185 b .L_resume_forward_branch
186
187.L_add_batch:
188 add x1, xFP, #OFF_FP_SHADOWFRAME
189 strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
190 ldr x0, [xFP, #OFF_FP_METHOD]
191 mov x2, xSELF
192 bl MterpAddHotnessBatch // (method, shadow_frame, self)
193 mov wPROFILE, w0 // restore new hotness countdown to wPROFILE
194 b .L_no_count_backwards
195
196/*
197 * Entered from the conditional branch handlers when OSR check request active on
198 * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
199 */
200.L_check_not_taken_osr:
201 mov x0, xSELF
202 add x1, xFP, #OFF_FP_SHADOWFRAME
203 mov x2, #2
204 EXPORT_PC
205 bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
206 cbnz x0, MterpOnStackReplacement
207 FETCH_ADVANCE_INST 2
208 GET_INST_OPCODE ip // extract opcode from wINST
209 GOTO_OPCODE ip // jump to next instruction
210
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000211
212/*
213 * Check for suspend check request. Assumes wINST already loaded, xPC advanced and
214 * still needs to get the opcode and branch to it, and flags are in lr.
215 */
216MterpCheckSuspendAndContinue:
217 ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh xIBASE
Hiroshi Yamauchi30493242016-11-03 13:06:52 -0700218 ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000219 b.ne check1
220 GET_INST_OPCODE ip // extract opcode from wINST
221 GOTO_OPCODE ip // jump to next instruction
222check1:
223 EXPORT_PC
224 mov x0, xSELF
225 bl MterpSuspendCheck // (self)
Bill Buzbeefd522f92016-02-11 22:37:42 +0000226 cbnz x0, MterpFallback // Something in the environment changed, switch interpreters
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000227 GET_INST_OPCODE ip // extract opcode from wINST
228 GOTO_OPCODE ip // jump to next instruction
229
230/*
Bill Buzbeefd522f92016-02-11 22:37:42 +0000231 * On-stack replacement has happened, and now we've returned from the compiled method.
232 */
233MterpOnStackReplacement:
234#if MTERP_LOGGING
235 mov x0, xSELF
236 add x1, xFP, #OFF_FP_SHADOWFRAME
Vladimir Markoe6220222016-07-20 14:25:30 +0100237 sxtw x2, wINST
Bill Buzbeefd522f92016-02-11 22:37:42 +0000238 bl MterpLogOSR
239#endif
240 mov x0, #1 // Signal normal return
241 b MterpDone
242
243/*
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000244 * Bail out to reference interpreter.
245 */
246MterpFallback:
247 EXPORT_PC
248#if MTERP_LOGGING
249 mov x0, xSELF
250 add x1, xFP, #OFF_FP_SHADOWFRAME
251 bl MterpLogFallback
252#endif
253MterpCommonFallback:
254 mov x0, #0 // signal retry with reference interpreter.
255 b MterpDone
256
257/*
258 * We pushed some registers on the stack in ExecuteMterpImpl, then saved
259 * SP and LR. Here we restore SP, restore the registers, and then restore
260 * LR to PC.
261 *
262 * On entry:
263 * uint32_t* xFP (should still be live, pointer to base of vregs)
264 */
265MterpExceptionReturn:
266 mov x0, #1 // signal return to caller.
267 b MterpDone
268MterpReturn:
269 ldr x2, [xFP, #OFF_FP_RESULT_REGISTER]
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000270 str x0, [x2]
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000271 mov x0, #1 // signal return to caller.
272MterpDone:
Bill Buzbee1d011d92016-04-04 16:59:29 +0000273/*
274 * At this point, we expect wPROFILE to be non-zero. If negative, hotness is disabled or we're
275 * checking for OSR. If greater than zero, we might have unreported hotness to register
276 * (the difference between the ending wPROFILE and the cached hotness counter). wPROFILE
277 * should only reach zero immediately after a hotness decrement, and is then reset to either
278 * a negative special state or the new non-zero countdown value.
279 */
280 cmp wPROFILE, #0
281 bgt MterpProfileActive // if > 0, we may have some counts to report.
Vladimir Marko112aa102016-12-01 11:53:54 +0000282 .cfi_remember_state
283 RESTORE_TWO_REGS fp, lr, 64
284 RESTORE_TWO_REGS xPC, xFP, 48
285 RESTORE_TWO_REGS xSELF, xINST, 32
286 RESTORE_TWO_REGS xIBASE, xREFS, 16
287 RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
Bill Buzbee1d011d92016-04-04 16:59:29 +0000288 ret
Vladimir Marko112aa102016-12-01 11:53:54 +0000289 .cfi_restore_state // Reset unwind info so following code unwinds.
290 .cfi_def_cfa_offset 80 // workaround for clang bug: 31975598
Bill Buzbee1d011d92016-04-04 16:59:29 +0000291
292MterpProfileActive:
293 mov xINST, x0 // stash return value
294 /* Report cached hotness counts */
295 ldr x0, [xFP, #OFF_FP_METHOD]
296 add x1, xFP, #OFF_FP_SHADOWFRAME
297 mov x2, xSELF
298 strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
299 bl MterpAddHotnessBatch // (method, shadow_frame, self)
300 mov x0, xINST // restore return value
Vladimir Marko112aa102016-12-01 11:53:54 +0000301 RESTORE_TWO_REGS fp, lr, 64
302 RESTORE_TWO_REGS xPC, xFP, 48
303 RESTORE_TWO_REGS xSELF, xINST, 32
304 RESTORE_TWO_REGS xIBASE, xREFS, 16
305 RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
Bill Buzbee3b0b4b92016-02-02 13:45:36 +0000306 ret
307
308 .cfi_endproc
309 .size ExecuteMterpImpl, .-ExecuteMterpImpl
310