Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 1 | /* |
| 2 | * =========================================================================== |
| 3 | * Common subroutines and data |
| 4 | * =========================================================================== |
| 5 | */ |
| 6 | |
| 7 | .text |
| 8 | .align 2 |
| 9 | |
| 10 | /* |
| 11 | * We've detected a condition that will result in an exception, but the exception |
| 12 | * has not yet been thrown. Just bail out to the reference interpreter to deal with it. |
| 13 | * TUNING: for consistency, we may want to just go ahead and handle these here. |
| 14 | */ |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 15 | common_errDivideByZero: |
| 16 | EXPORT_PC |
| 17 | #if MTERP_LOGGING |
| 18 | movl rSELF, %eax |
| 19 | movl %eax, OUT_ARG0(%esp) |
| 20 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 21 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 22 | call SYMBOL(MterpLogDivideByZeroException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 23 | #endif |
| 24 | jmp MterpCommonFallback |
| 25 | |
| 26 | common_errArrayIndex: |
| 27 | EXPORT_PC |
| 28 | #if MTERP_LOGGING |
| 29 | movl rSELF, %eax |
| 30 | movl %eax, OUT_ARG0(%esp) |
| 31 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 32 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 33 | call SYMBOL(MterpLogArrayIndexException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 34 | #endif |
| 35 | jmp MterpCommonFallback |
| 36 | |
| 37 | common_errNegativeArraySize: |
| 38 | EXPORT_PC |
| 39 | #if MTERP_LOGGING |
| 40 | movl rSELF, %eax |
| 41 | movl %eax, OUT_ARG0(%esp) |
| 42 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 43 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 44 | call SYMBOL(MterpLogNegativeArraySizeException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 45 | #endif |
| 46 | jmp MterpCommonFallback |
| 47 | |
| 48 | common_errNoSuchMethod: |
| 49 | EXPORT_PC |
| 50 | #if MTERP_LOGGING |
| 51 | movl rSELF, %eax |
| 52 | movl %eax, OUT_ARG0(%esp) |
| 53 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 54 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 55 | call SYMBOL(MterpLogNoSuchMethodException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 56 | #endif |
| 57 | jmp MterpCommonFallback |
| 58 | |
| 59 | common_errNullObject: |
| 60 | EXPORT_PC |
| 61 | #if MTERP_LOGGING |
| 62 | movl rSELF, %eax |
| 63 | movl %eax, OUT_ARG0(%esp) |
| 64 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 65 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 66 | call SYMBOL(MterpLogNullObjectException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 67 | #endif |
| 68 | jmp MterpCommonFallback |
| 69 | |
| 70 | common_exceptionThrown: |
| 71 | EXPORT_PC |
| 72 | #if MTERP_LOGGING |
| 73 | movl rSELF, %eax |
| 74 | movl %eax, OUT_ARG0(%esp) |
| 75 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 76 | movl %ecx, OUT_ARG0(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 77 | call SYMBOL(MterpLogExceptionThrownException) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 78 | #endif |
| 79 | jmp MterpCommonFallback |
| 80 | |
| 81 | MterpSuspendFallback: |
| 82 | EXPORT_PC |
| 83 | #if MTERP_LOGGING |
| 84 | movl rSELF, %eax |
| 85 | movl %eax, OUT_ARG0(%esp) |
| 86 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 87 | movl %ecx, OUT_ARG0(%esp) |
| 88 | movl THREAD_FLAGS_OFFSET(%eax), %eax |
| 89 | movl %eax, OUT_ARG2(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 90 | call SYMBOL(MterpLogSuspendFallback) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 91 | #endif |
| 92 | jmp MterpCommonFallback |
| 93 | |
| 94 | /* |
| 95 | * If we're here, something is out of the ordinary. If there is a pending |
| 96 | * exception, handle it. Otherwise, roll back and retry with the reference |
| 97 | * interpreter. |
| 98 | */ |
| 99 | MterpPossibleException: |
| 100 | movl rSELF, %eax |
| 101 | testl $$-1, THREAD_EXCEPTION_OFFSET(%eax) |
| 102 | jz MterpFallback |
| 103 | /* intentional fallthrough - handle pending exception. */ |
| 104 | |
| 105 | /* |
| 106 | * On return from a runtime helper routine, we've found a pending exception. |
| 107 | * Can we handle it here - or need to bail out to caller? |
| 108 | * |
| 109 | */ |
| 110 | MterpException: |
| 111 | movl rSELF, %eax |
| 112 | movl %eax, OUT_ARG0(%esp) |
| 113 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 114 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 115 | call SYMBOL(MterpHandleException) |
Serguei Katkov | ff8579e | 2016-02-17 11:30:23 +0600 | [diff] [blame] | 116 | testb %al, %al |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 117 | jz MterpExceptionReturn |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 118 | movl OFF_FP_CODE_ITEM(rFP), %eax |
| 119 | movl OFF_FP_DEX_PC(rFP), %ecx |
| 120 | lea CODEITEM_INSNS_OFFSET(%eax), rPC |
| 121 | lea (rPC, %ecx, 2), rPC |
| 122 | movl rPC, OFF_FP_DEX_PC_PTR(rFP) |
Bill Buzbee | 481352d | 2016-02-25 17:37:46 +0000 | [diff] [blame] | 123 | /* Do we need to switch interpreters? */ |
| 124 | call SYMBOL(MterpShouldSwitchInterpreters) |
| 125 | testb %al, %al |
| 126 | jnz MterpFallback |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 127 | /* resume execution at catch block */ |
Bill Buzbee | 481352d | 2016-02-25 17:37:46 +0000 | [diff] [blame] | 128 | REFRESH_IBASE |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 129 | FETCH_INST |
| 130 | GOTO_NEXT |
| 131 | /* NOTE: no fallthrough */ |
| 132 | |
| 133 | /* |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 134 | * Common handling for branches with support for Jit profiling. |
| 135 | * On entry: |
| 136 | * rINST <= signed offset |
| 137 | * condition bits <= set to establish sign of offset (use "NoFlags" entry if not) |
| 138 | * |
| 139 | * We have quite a few different cases for branch profiling, OSR detection and |
| 140 | * suspend check support here. |
| 141 | * |
| 142 | * Taken backward branches: |
| 143 | * If profiling active, do hotness countdown and report if we hit zero. |
| 144 | * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so. |
| 145 | * Is there a pending suspend request? If so, suspend. |
| 146 | * |
| 147 | * Taken forward branches and not-taken backward branches: |
| 148 | * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so. |
| 149 | * |
| 150 | * Our most common case is expected to be a taken backward branch with active jit profiling, |
| 151 | * but no full OSR check and no pending suspend request. |
| 152 | * Next most common case is not-taken branch with no full OSR check. |
| 153 | * |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 154 | */ |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 155 | MterpCommonTakenBranch: |
| 156 | jg .L_forward_branch # don't add forward branches to hotness |
| 157 | /* |
| 158 | * We need to subtract 1 from positive values and we should not see 0 here, |
| 159 | * so we may use the result of the comparison with -1. |
| 160 | */ |
| 161 | #if JIT_CHECK_OSR != -1 |
| 162 | # error "JIT_CHECK_OSR must be -1." |
| 163 | #endif |
| 164 | cmpw $$JIT_CHECK_OSR, rPROFILE |
| 165 | je .L_osr_check |
| 166 | decw rPROFILE |
| 167 | je .L_add_batch # counted down to zero - report |
| 168 | .L_resume_backward_branch: |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 169 | movl rSELF, %eax |
Hiroshi Yamauchi | 3049324 | 2016-11-03 13:06:52 -0700 | [diff] [blame] | 170 | testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax) |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 171 | leal (rPC, rINST, 2), rPC |
| 172 | FETCH_INST |
| 173 | jnz .L_suspend_request_pending |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 174 | REFRESH_IBASE |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 175 | GOTO_NEXT |
| 176 | |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 177 | .L_suspend_request_pending: |
| 178 | EXPORT_PC |
| 179 | movl %eax, OUT_ARG0(%esp) # rSELF in eax |
| 180 | call SYMBOL(MterpSuspendCheck) # (self) |
| 181 | testb %al, %al |
| 182 | jnz MterpFallback |
| 183 | REFRESH_IBASE # might have changed during suspend |
| 184 | GOTO_NEXT |
| 185 | |
| 186 | .L_no_count_backwards: |
| 187 | cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry? |
| 188 | jne .L_resume_backward_branch |
| 189 | .L_osr_check: |
| 190 | EXPORT_PC |
| 191 | movl rSELF, %eax |
| 192 | movl %eax, OUT_ARG0(%esp) |
| 193 | leal OFF_FP_SHADOWFRAME(rFP), %ecx |
| 194 | movl %ecx, OUT_ARG1(%esp) |
| 195 | movl rINST, OUT_ARG2(%esp) |
| 196 | call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset) |
| 197 | testb %al, %al |
| 198 | jz .L_resume_backward_branch |
| 199 | jmp MterpOnStackReplacement |
| 200 | |
| 201 | .L_forward_branch: |
| 202 | cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry? |
| 203 | je .L_check_osr_forward |
| 204 | .L_resume_forward_branch: |
| 205 | leal (rPC, rINST, 2), rPC |
| 206 | FETCH_INST |
| 207 | GOTO_NEXT |
| 208 | |
| 209 | .L_check_osr_forward: |
| 210 | EXPORT_PC |
| 211 | movl rSELF, %eax |
| 212 | movl %eax, OUT_ARG0(%esp) |
| 213 | leal OFF_FP_SHADOWFRAME(rFP), %ecx |
| 214 | movl %ecx, OUT_ARG1(%esp) |
| 215 | movl rINST, OUT_ARG2(%esp) |
| 216 | call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset) |
| 217 | testb %al, %al |
| 218 | REFRESH_IBASE |
| 219 | jz .L_resume_forward_branch |
| 220 | jmp MterpOnStackReplacement |
| 221 | |
| 222 | .L_add_batch: |
| 223 | movl OFF_FP_METHOD(rFP), %eax |
| 224 | movl %eax, OUT_ARG0(%esp) |
| 225 | leal OFF_FP_SHADOWFRAME(rFP), %ecx |
| 226 | movl %ecx, OUT_ARG1(%esp) |
| 227 | movl rSELF, %eax |
| 228 | movl %eax, OUT_ARG2(%esp) |
| 229 | call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self) |
| 230 | jmp .L_no_count_backwards |
| 231 | |
| 232 | /* |
| 233 | * Entered from the conditional branch handlers when OSR check request active on |
| 234 | * not-taken path. All Dalvik not-taken conditional branch offsets are 2. |
| 235 | */ |
| 236 | .L_check_not_taken_osr: |
buzbee | 963758d | 2016-04-28 16:08:44 -0700 | [diff] [blame] | 237 | EXPORT_PC |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 238 | movl rSELF, %eax |
| 239 | movl %eax, OUT_ARG0(%esp) |
| 240 | leal OFF_FP_SHADOWFRAME(rFP), %ecx |
| 241 | movl %ecx, OUT_ARG1(%esp) |
Bill Buzbee | 9afaac4 | 2016-04-04 16:59:35 +0000 | [diff] [blame] | 242 | movl $$2, OUT_ARG2(%esp) |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 243 | call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset) |
| 244 | testb %al, %al |
| 245 | REFRESH_IBASE |
| 246 | jnz MterpOnStackReplacement |
| 247 | ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 |
| 248 | |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 249 | /* |
buzbee | 2de973d | 2016-02-23 13:25:00 -0800 | [diff] [blame] | 250 | * On-stack replacement has happened, and now we've returned from the compiled method. |
| 251 | */ |
| 252 | MterpOnStackReplacement: |
| 253 | #if MTERP_LOGGING |
| 254 | movl rSELF, %eax |
| 255 | movl %eax, OUT_ARG0(%esp) |
| 256 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 257 | movl %ecx, OUT_ARG1(%esp) |
| 258 | movl rINST, OUT_ARG2(%esp) |
| 259 | call SYMBOL(MterpLogOSR) |
| 260 | #endif |
| 261 | movl $$1, %eax |
| 262 | jmp MterpDone |
| 263 | |
| 264 | /* |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 265 | * Bail out to reference interpreter. |
| 266 | */ |
| 267 | MterpFallback: |
| 268 | EXPORT_PC |
| 269 | #if MTERP_LOGGING |
| 270 | movl rSELF, %eax |
| 271 | movl %eax, OUT_ARG0(%esp) |
| 272 | lea OFF_FP_SHADOWFRAME(rFP), %ecx |
| 273 | movl %ecx, OUT_ARG1(%esp) |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 274 | call SYMBOL(MterpLogFallback) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 275 | #endif |
| 276 | MterpCommonFallback: |
| 277 | xor %eax, %eax |
| 278 | jmp MterpDone |
| 279 | |
| 280 | /* |
| 281 | * On entry: |
| 282 | * uint32_t* rFP (should still be live, pointer to base of vregs) |
| 283 | */ |
| 284 | MterpExceptionReturn: |
| 285 | movl $$1, %eax |
| 286 | jmp MterpDone |
| 287 | MterpReturn: |
| 288 | movl OFF_FP_RESULT_REGISTER(rFP), %edx |
| 289 | movl %eax, (%edx) |
| 290 | movl %ecx, 4(%edx) |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 291 | mov $$1, %eax |
| 292 | MterpDone: |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 293 | /* |
| 294 | * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're |
| 295 | * checking for OSR. If greater than zero, we might have unreported hotness to register |
| 296 | * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE |
| 297 | * should only reach zero immediately after a hotness decrement, and is then reset to either |
| 298 | * a negative special state or the new non-zero countdown value. |
| 299 | */ |
| 300 | cmpw $$0, rPROFILE |
| 301 | jle MRestoreFrame # if > 0, we may have some counts to report. |
| 302 | |
| 303 | movl %eax, rINST # stash return value |
| 304 | /* Report cached hotness counts */ |
| 305 | movl OFF_FP_METHOD(rFP), %eax |
| 306 | movl %eax, OUT_ARG0(%esp) |
| 307 | leal OFF_FP_SHADOWFRAME(rFP), %ecx |
| 308 | movl %ecx, OUT_ARG1(%esp) |
| 309 | movl rSELF, %eax |
| 310 | movl %eax, OUT_ARG2(%esp) |
| 311 | call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self) |
| 312 | movl rINST, %eax # restore return value |
| 313 | |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 314 | /* pop up frame */ |
Bill Buzbee | d634208 | 2016-04-04 16:59:10 +0000 | [diff] [blame] | 315 | MRestoreFrame: |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 316 | addl $$FRAME_SIZE, %esp |
| 317 | .cfi_adjust_cfa_offset -FRAME_SIZE |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 318 | |
Serguei Katkov | 897338d | 2016-03-01 15:53:22 +0600 | [diff] [blame] | 319 | /* Restore callee save register */ |
| 320 | POP %ebx |
| 321 | POP %esi |
| 322 | POP %edi |
| 323 | POP %ebp |
| 324 | ret |
Bill Buzbee | 7c58bd4 | 2016-01-20 20:46:01 +0000 | [diff] [blame] | 325 | .cfi_endproc |
Serguei Katkov | 05dfaaa | 2016-01-28 08:21:26 +0600 | [diff] [blame] | 326 | SIZE(ExecuteMterpImpl,ExecuteMterpImpl) |