MIPS: Follow-up to "Allow deoptimization when returning from a runtime method"
This is a MIPS-specific follow-up to
https://android-review.googlesource.com/442545.
Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU
Test: testrunner.py --target --optimizing
Test: same tests as above on CI20
Test: booted MIPS32R2 in QEMU
Bug: 33616143
Change-Id: I3478f1ac332b0b97578225fd55ac0fccdfa4e33f
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index b876353..74e0a7a 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -2317,58 +2317,50 @@
.extern artInstrumentationMethodExitFromCode
ENTRY art_quick_instrumentation_entry
SETUP_SAVE_REFS_AND_ARGS_FRAME
- sw $a0, 28($sp) # save arg0 in free arg slot
- addiu $a3, $sp, ARG_SLOT_SIZE # Pass $sp.
- la $t9, artInstrumentationMethodEntryFromCode
- jalr $t9 # (Method*, Object*, Thread*, SP)
- move $a2, rSELF # pass Thread::Current
- beqz $v0, .Ldeliver_instrumentation_entry_exception
- move $t9, $v0 # $t9 holds reference to code
- lw $a0, 28($sp) # restore arg0 from free arg slot
+ sw $a0, 28($sp) # save arg0 in free arg slot
+ addiu $a3, $sp, ARG_SLOT_SIZE # Pass $sp.
+ la $t9, artInstrumentationMethodEntryFromCode
+ jalr $t9 # (Method*, Object*, Thread*, SP)
+ move $a2, rSELF # pass Thread::Current
+ beqz $v0, .Ldeliver_instrumentation_entry_exception
+ move $t9, $v0 # $t9 holds reference to code
+ lw $a0, 28($sp) # restore arg0 from free arg slot
RESTORE_SAVE_REFS_AND_ARGS_FRAME
- jalr $t9 # call method
- nop
-END art_quick_instrumentation_entry
- /* intentional fallthrough */
- .global art_quick_instrumentation_exit
-art_quick_instrumentation_exit:
- .cfi_startproc
- addiu $t9, $ra, 4 # put current address into $t9 to rebuild $gp
- .cpload $t9
- move $ra, $zero # link register is to here, so clobber with 0 for later checks
-
- SETUP_SAVE_REFS_ONLY_FRAME
- addiu $sp, $sp, -16 # allocate temp storage on the stack
- .cfi_adjust_cfa_offset 16
- sw $v0, ARG_SLOT_SIZE+8($sp)
- .cfi_rel_offset 2, ARG_SLOT_SIZE+8
- sw $v1, ARG_SLOT_SIZE+12($sp)
- .cfi_rel_offset 3, ARG_SLOT_SIZE+12
- s.d $f0, ARG_SLOT_SIZE($sp)
- addiu $a3, $sp, ARG_SLOT_SIZE # Pass fpr_res pointer.
- addiu $a2, $sp, ARG_SLOT_SIZE+8 # Pass gpr_res pointer.
- addiu $a1, $sp, ARG_SLOT_SIZE+16 # Pass $sp (remove arg slots and temp storage).
- la $t9, artInstrumentationMethodExitFromCode
- jalr $t9 # (Thread*, SP, gpr_res*, fpr_res*)
- move $a0, rSELF # Pass Thread::Current.
- move $t9, $v0 # Set aside returned link register.
- move $ra, $v1 # Set link register for deoptimization.
- lw $v0, ARG_SLOT_SIZE+8($sp) # Restore return values.
- lw $v1, ARG_SLOT_SIZE+12($sp)
- l.d $f0, ARG_SLOT_SIZE($sp)
- addiu $sp, $sp, 16
- .cfi_adjust_cfa_offset -16
- RESTORE_SAVE_REFS_ONLY_FRAME
- beqz $t9, .Ldo_deliver_instrumentation_exception
- nop # Deliver exception if we got nullptr as function.
- jalr $zero, $t9 # Otherwise, return.
+ la $ra, art_quick_instrumentation_exit
+ jalr $zero, $t9 # call method, returning to art_quick_instrumentation_exit
nop
.Ldeliver_instrumentation_entry_exception:
- # Deliver exception for art_quick_instrumentation_entry placed after
- # art_quick_instrumentation_exit so that the fallthrough works.
RESTORE_SAVE_REFS_AND_ARGS_FRAME
-.Ldo_deliver_instrumentation_exception:
DELIVER_PENDING_EXCEPTION
+END art_quick_instrumentation_entry
+
+ENTRY_NO_GP art_quick_instrumentation_exit
+ move $ra, $zero # RA points here, so clobber with 0 for later checks.
+ SETUP_SAVE_EVERYTHING_FRAME # Allocates ARG_SLOT_SIZE bytes at the bottom of the stack.
+ move $s2, $gp # Preserve $gp across the call for exception delivery.
+
+ addiu $a3, $sp, ARG_SLOT_SIZE+16 # Pass fpr_res pointer ($f0 in SAVE_EVERYTHING_FRAME).
+ addiu $a2, $sp, ARG_SLOT_SIZE+148 # Pass gpr_res pointer ($v0 in SAVE_EVERYTHING_FRAME).
+ addiu $a1, $sp, ARG_SLOT_SIZE # Pass $sp.
+ la $t9, artInstrumentationMethodExitFromCode
+ jalr $t9 # (Thread*, SP, gpr_res*, fpr_res*)
+ move $a0, rSELF # Pass Thread::Current.
+
+ beqz $v0, .Ldo_deliver_instrumentation_exception
+ move $gp, $s2 # Deliver exception if we got nullptr as function.
+ bnez $v1, .Ldeoptimize
+
+ # Normal return.
+ sw $v0, (ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING-4)($sp) # Set return pc.
+ RESTORE_SAVE_EVERYTHING_FRAME
+ jalr $zero, $ra
+ nop
+.Ldo_deliver_instrumentation_exception:
+ DELIVER_PENDING_EXCEPTION_FRAME_READY
+.Ldeoptimize:
+ b art_quick_deoptimize
+ sw $v1, (ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING-4)($sp)
+ # Fake a call from instrumentation return pc.
END art_quick_instrumentation_exit
/*
@@ -2376,11 +2368,41 @@
* will long jump to the upcall with a special exception of -1.
*/
.extern artDeoptimize
-ENTRY art_quick_deoptimize
- SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
- la $t9, artDeoptimize
- jalr $t9 # (Thread*)
- move $a0, rSELF # pass Thread::current
+ENTRY_NO_GP_CUSTOM_CFA art_quick_deoptimize, ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING
+ # SETUP_SAVE_EVERYTHING_FRAME has been done by art_quick_instrumentation_exit.
+ .cfi_rel_offset 31, ARG_SLOT_SIZE+252
+ .cfi_rel_offset 30, ARG_SLOT_SIZE+248
+ .cfi_rel_offset 28, ARG_SLOT_SIZE+244
+ .cfi_rel_offset 25, ARG_SLOT_SIZE+240
+ .cfi_rel_offset 24, ARG_SLOT_SIZE+236
+ .cfi_rel_offset 23, ARG_SLOT_SIZE+232
+ .cfi_rel_offset 22, ARG_SLOT_SIZE+228
+ .cfi_rel_offset 21, ARG_SLOT_SIZE+224
+ .cfi_rel_offset 20, ARG_SLOT_SIZE+220
+ .cfi_rel_offset 19, ARG_SLOT_SIZE+216
+ .cfi_rel_offset 18, ARG_SLOT_SIZE+212
+ .cfi_rel_offset 17, ARG_SLOT_SIZE+208
+ .cfi_rel_offset 16, ARG_SLOT_SIZE+204
+ .cfi_rel_offset 15, ARG_SLOT_SIZE+200
+ .cfi_rel_offset 14, ARG_SLOT_SIZE+196
+ .cfi_rel_offset 13, ARG_SLOT_SIZE+192
+ .cfi_rel_offset 12, ARG_SLOT_SIZE+188
+ .cfi_rel_offset 11, ARG_SLOT_SIZE+184
+ .cfi_rel_offset 10, ARG_SLOT_SIZE+180
+ .cfi_rel_offset 9, ARG_SLOT_SIZE+176
+ .cfi_rel_offset 8, ARG_SLOT_SIZE+172
+ .cfi_rel_offset 7, ARG_SLOT_SIZE+168
+ .cfi_rel_offset 6, ARG_SLOT_SIZE+164
+ .cfi_rel_offset 5, ARG_SLOT_SIZE+160
+ .cfi_rel_offset 4, ARG_SLOT_SIZE+156
+ .cfi_rel_offset 3, ARG_SLOT_SIZE+152
+ .cfi_rel_offset 2, ARG_SLOT_SIZE+148
+ .cfi_rel_offset 1, ARG_SLOT_SIZE+144
+
+ la $t9, artDeoptimize
+ jalr $t9 # (Thread*)
+ move $a0, rSELF # pass Thread::current
+ break
END art_quick_deoptimize
/*
@@ -2388,7 +2410,7 @@
* will long jump to the upcall with a special exception of -1.
*/
.extern artDeoptimizeFromCompiledCode
-ENTRY art_quick_deoptimize_from_compiled_code
+ENTRY_NO_GP art_quick_deoptimize_from_compiled_code
SETUP_SAVE_EVERYTHING_FRAME
la $t9, artDeoptimizeFromCompiledCode
jalr $t9 # (DeoptimizationKind, Thread*)
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index eeaae3c..1817502 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -2203,53 +2203,47 @@
ENTRY art_quick_instrumentation_entry
SETUP_SAVE_REFS_AND_ARGS_FRAME
# Preserve $a0 knowing there is a spare slot in kSaveRefsAndArgs.
- sd $a0, 8($sp) # Save arg0.
- move $a3, $sp # Pass $sp.
- jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, SP)
- move $a2, rSELF # pass Thread::Current
- beqzc $v0, .Ldeliver_instrumentation_entry_exception
- # Deliver exception if we got nullptr as function.
- move $t9, $v0 # $t9 holds reference to code
- ld $a0, 8($sp) # Restore arg0.
+ sd $a0, 8($sp) # Save arg0.
+ move $a3, $sp # Pass $sp.
+ jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, SP)
+ move $a2, rSELF # pass Thread::Current
+ beqzc $v0, .Ldeliver_instrumentation_entry_exception
+ # Deliver exception if we got nullptr as function.
+ move $t9, $v0 # $t9 holds reference to code
+ ld $a0, 8($sp) # Restore arg0.
RESTORE_SAVE_REFS_AND_ARGS_FRAME
- jalr $t9 # call method
- nop
-END art_quick_instrumentation_entry
- /* intentional fallthrough */
- .global art_quick_instrumentation_exit
-art_quick_instrumentation_exit:
- .cfi_startproc
- SETUP_GP
- move $ra, $zero # link register is to here, so clobber with 0 for later checks
- SETUP_SAVE_REFS_ONLY_FRAME
- daddiu $sp, $sp, -16 # save return values and set up args
- .cfi_adjust_cfa_offset 16
- sd $v0, 0($sp)
- .cfi_rel_offset 2, 0
- s.d $f0, 8($sp)
- daddiu $a3, $sp, 8 # Pass fpr_res pointer.
- move $a2, $sp # Pass gpr_res pointer.
- daddiu $a1, $sp, 16 # Pass $sp.
- jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res*, fpr_res*)
- move $a0, rSELF # pass Thread::Current
-
- move $t9, $v0 # set aside returned link register
- move $ra, $v1 # set link register for deoptimization
- ld $v0, 0($sp) # restore return values
- l.d $f0, 8($sp)
- daddiu $sp, $sp, 16
- .cfi_adjust_cfa_offset -16
- RESTORE_SAVE_REFS_ONLY_FRAME
- beqz $t9, .Ldo_deliver_instrumentation_exception
- nop # Deliver exception if we got nullptr as function.
- jalr $zero, $t9 # Otherwise, return.
- nop
+ dla $ra, art_quick_instrumentation_exit
+ jic $t9, 0 # call method, returning to art_quick_instrumentation_exit
.Ldeliver_instrumentation_entry_exception:
- # Deliver exception for art_quick_instrumentation_entry placed after
- # art_quick_instrumentation_exit so that the fallthrough works.
RESTORE_SAVE_REFS_AND_ARGS_FRAME
-.Ldo_deliver_instrumentation_exception:
DELIVER_PENDING_EXCEPTION
+END art_quick_instrumentation_entry
+
+ENTRY_NO_GP art_quick_instrumentation_exit
+ move $ra, $zero # RA points here, so clobber with 0 for later checks.
+ SETUP_SAVE_EVERYTHING_FRAME
+
+ daddiu $a3, $sp, 16 # Pass fpr_res pointer ($f0 in SAVE_EVERYTHING_FRAME).
+ daddiu $a2, $sp, 280 # Pass gpr_res pointer ($v0 in SAVE_EVERYTHING_FRAME).
+ move $a1, $sp # Pass $sp.
+ jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res*, fpr_res*)
+ move $a0, rSELF # pass Thread::Current
+
+ beqzc $v0, .Ldo_deliver_instrumentation_exception
+ # Deliver exception if we got nullptr as function.
+ nop
+ bnez $v1, .Ldeoptimize
+
+ # Normal return.
+ sd $v0, (FRAME_SIZE_SAVE_EVERYTHING-8)($sp) # Set return pc.
+ RESTORE_SAVE_EVERYTHING_FRAME
+ jic $ra, 0
+.Ldo_deliver_instrumentation_exception:
+ DELIVER_PENDING_EXCEPTION_FRAME_READY
+.Ldeoptimize:
+ b art_quick_deoptimize
+ sd $v1, (FRAME_SIZE_SAVE_EVERYTHING-8)($sp)
+ # Fake a call from instrumentation return pc.
END art_quick_instrumentation_exit
/*
@@ -2257,11 +2251,40 @@
* will long jump to the upcall with a special exception of -1.
*/
.extern artDeoptimize
- .extern artEnterInterpreterFromDeoptimize
-ENTRY art_quick_deoptimize
- SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
- jal artDeoptimize # artDeoptimize(Thread*)
- move $a0, rSELF # pass Thread::current
+ENTRY_NO_GP_CUSTOM_CFA art_quick_deoptimize, FRAME_SIZE_SAVE_EVERYTHING
+ # SETUP_SAVE_EVERYTHING_FRAME has been done by art_quick_instrumentation_exit.
+ .cfi_rel_offset 31, 488
+ .cfi_rel_offset 30, 480
+ .cfi_rel_offset 28, 472
+ .cfi_rel_offset 25, 464
+ .cfi_rel_offset 24, 456
+ .cfi_rel_offset 23, 448
+ .cfi_rel_offset 22, 440
+ .cfi_rel_offset 21, 432
+ .cfi_rel_offset 20, 424
+ .cfi_rel_offset 19, 416
+ .cfi_rel_offset 18, 408
+ .cfi_rel_offset 17, 400
+ .cfi_rel_offset 16, 392
+ .cfi_rel_offset 15, 384
+ .cfi_rel_offset 14, 376
+ .cfi_rel_offset 13, 368
+ .cfi_rel_offset 12, 360
+ .cfi_rel_offset 11, 352
+ .cfi_rel_offset 10, 344
+ .cfi_rel_offset 9, 336
+ .cfi_rel_offset 8, 328
+ .cfi_rel_offset 7, 320
+ .cfi_rel_offset 6, 312
+ .cfi_rel_offset 5, 304
+ .cfi_rel_offset 4, 296
+ .cfi_rel_offset 3, 288
+ .cfi_rel_offset 2, 280
+ .cfi_rel_offset 1, 272
+
+ jal artDeoptimize # artDeoptimize(Thread*)
+ move $a0, rSELF # pass Thread::current
+ break
END art_quick_deoptimize
/*