MIPS: Fix art_quick_instrumentation_entry/exit
This is a follow-up change for
Iab229353fae23c2ea27c2b698c831627a9f861b1.
This fixes following tests for both MIPS32 and MIPS64:
* 099-vmdebug
* 304-method-tracing
* 545-tracing-and-jit
* 570-checker-osr
* 597-deopt-new-string
* 802-deoptimization
* 988-method-trace
* 989-method-trace-throw
Test: ./testrunner.py --optimizing --target in QEMU (MIPS64R6)
Test: ./testrunner.py --optimizing --target on CI20 (MIPS32R2)
Change-Id: I064588283b65971f07150eb30a1fcf90c765eb40
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index d1da67f..a5a65e6 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -2003,10 +2003,11 @@
ENTRY art_quick_instrumentation_entry
SETUP_SAVE_REFS_AND_ARGS_FRAME
sw $a0, 28($sp) # save arg0 in free arg slot
- move $a3, $ra # pass $ra
+ addiu $a3, $sp, ARG_SLOT_SIZE # Pass $sp.
la $t9, artInstrumentationMethodEntryFromCode
- jalr $t9 # (Method*, Object*, Thread*, LR)
+ 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
@@ -2024,26 +2025,35 @@
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+12($sp)
- .cfi_rel_offset 2, ARG_SLOT_SIZE+12
- sw $v1, ARG_SLOT_SIZE+8($sp)
- .cfi_rel_offset 3, ARG_SLOT_SIZE+8
+ 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)
- s.d $f0, 16($sp) # pass fpr result
- move $a2, $v0 # pass gpr result
- move $a3, $v1
- addiu $a1, $sp, ARG_SLOT_SIZE+16 # pass $sp (remove arg slots and temp storage)
+ 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+12($sp) # restore return values
- lw $v1, ARG_SLOT_SIZE+8($sp)
+ 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)
- jalr $zero, $t9 # return
- addiu $sp, $sp, ARG_SLOT_SIZE+FRAME_SIZE_SAVE_REFS_ONLY+16 # restore stack
- .cfi_adjust_cfa_offset -(ARG_SLOT_SIZE+FRAME_SIZE_SAVE_REFS_ONLY+16)
+ 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.
+ 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_exit
/*
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index c9eeb7c..10074fd 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1930,16 +1930,15 @@
.extern artInstrumentationMethodExitFromCode
ENTRY art_quick_instrumentation_entry
SETUP_SAVE_REFS_AND_ARGS_FRAME
- daddiu $sp, $sp, -16 # space for saving arg0
- .cfi_adjust_cfa_offset 16
- sd $a0, 0($sp) # save arg0
- move $a3, $ra # pass $ra
- jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, RA)
+ # 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, 0($sp) # restore arg0
- daddiu $sp, $sp, 16 # remove args
- .cfi_adjust_cfa_offset -16
+ ld $a0, 8($sp) # Restore arg0.
RESTORE_SAVE_REFS_AND_ARGS_FRAME
jalr $t9 # call method
nop
@@ -1951,28 +1950,34 @@
SETUP_GP
move $ra, $zero # link register is to here, so clobber with 0 for later checks
SETUP_SAVE_REFS_ONLY_FRAME
- move $t0, $sp # remember bottom of caller's 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)
- mov.d $f15, $f0 # pass fpr result
- move $a2, $v0 # pass gpr result
- move $a1, $t0 # pass $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
- jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res, fpr_res)
- .cpreturn # Restore gp from t8 in branch delay slot. gp is not used anymore,
- # and t8 may be clobbered in artInstrumentationMethodExitFromCode.
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)
- jalr $zero, $t9 # return
- # restore stack, 16 bytes of saved values + ref_only callee save frame
- daddiu $sp, $sp, 16+FRAME_SIZE_SAVE_REFS_ONLY
- .cfi_adjust_cfa_offset -(16+FRAME_SIZE_SAVE_REFS_ONLY)
+ 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
+.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_exit
/*