MIPS: Change remaining entrypoints to save everything.
This also fixes two issues:
1. Missing restore of the callee-clobbered gp register on
MIPS32
2. Incorrect DCHECK causing test 916-obsolete-jit to fail
on MIPS32 in the ART_READ_BARRIER_TYPE=TABLELOOKUP
configuration
Test: booted MIPS32R2 in QEMU
Test: test-art-target-gtest
Test: testrunner.py --target --optimizing
Test: booted MIPS64 (with 2nd arch MIPS32R2) in QEMU
Test: same tests as above for both MIPS32R6 and MIPS64R6
Test: repeat all of the above in two configurations:
ART_READ_BARRIER_TYPE=TABLELOOKUP,
ART_USE_READ_BARRIER=false.
Change-Id: I06a3c24579242a632ec8c373c233217d558a8401
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 61a3a04..90bbfa2 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -421,7 +421,7 @@
SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP
.endm
-.macro RESTORE_SAVE_EVERYTHING_FRAME
+.macro RESTORE_SAVE_EVERYTHING_FRAME restore_a0=1
addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack
.cfi_adjust_cfa_offset -ARG_SLOT_SIZE
@@ -490,8 +490,10 @@
.cfi_restore 6
lw $a1, 160($sp)
.cfi_restore 5
+ .if \restore_a0
lw $a0, 156($sp)
.cfi_restore 4
+ .endif
lw $v1, 152($sp)
.cfi_restore 3
lw $v0, 148($sp)
@@ -507,16 +509,26 @@
.endm
/*
- * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
- * exception is Thread::Current()->exception_
+ * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending
+ * exception is Thread::Current()->exception_ when the runtime method frame is ready.
+ * Requires $gp properly set up.
*/
-.macro DELIVER_PENDING_EXCEPTION
- SETUP_SAVE_ALL_CALLEE_SAVES_FRAME # save callee saves for throw
+.macro DELIVER_PENDING_EXCEPTION_FRAME_READY
la $t9, artDeliverPendingExceptionFromCode
jalr $zero, $t9 # artDeliverPendingExceptionFromCode(Thread*)
move $a0, rSELF # pass Thread::Current
.endm
+ /*
+ * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending
+ * exception is Thread::Current()->exception_.
+ * Requires $gp properly set up.
+ */
+.macro DELIVER_PENDING_EXCEPTION
+ SETUP_SAVE_ALL_CALLEE_SAVES_FRAME # save callee saves for throw
+ DELIVER_PENDING_EXCEPTION_FRAME_READY
+.endm
+
.macro RETURN_IF_NO_EXCEPTION
lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
RESTORE_SAVE_REFS_ONLY_FRAME
@@ -1660,30 +1672,51 @@
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
+// Macro for string and type resolution and initialization.
+// $a0 is both input and output.
+.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint
+ .extern \entrypoint
+ENTRY_NO_GP \name
+ SETUP_SAVE_EVERYTHING_FRAME # Save everything in case of GC.
+ move $s2, $gp # Preserve $gp across the call for exception delivery.
+ la $t9, \entrypoint
+ jalr $t9 # (uint32_t index, Thread*)
+ move $a1, rSELF # Pass Thread::Current (in delay slot).
+ beqz $v0, 1f # Success?
+ move $a0, $v0 # Move result to $a0 (in delay slot).
+ RESTORE_SAVE_EVERYTHING_FRAME 0 # Restore everything except $a0.
+ jalr $zero, $ra # Return on success.
+ nop
+1:
+ move $gp, $s2
+ DELIVER_PENDING_EXCEPTION_FRAME_READY
+END \name
+.endm
+
/*
* Entry from managed code to resolve a string, this stub will allocate a String and deliver an
* exception on error. On success the String is returned. A0 holds the string index. The fast
* path check for hit in strings cache has already been performed.
*/
-ONE_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
/*
* Entry from managed code when uninitialized static storage, this stub will run the class
* initializer and deliver the exception on error. On success the static storage base is
* returned.
*/
-ONE_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
/*
* Entry from managed code when dex cache misses for a type_idx.
*/
-ONE_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode
/*
* Entry from managed code when type_idx needs to be checked for access and dex cache may also
* miss.
*/
-ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
/*
* Called by managed code when the value in rSUSPEND has been decremented to 0.
@@ -1854,7 +1887,8 @@
nop
2:
- lw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)
+ lw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)
+ move $gp, $s3 # restore $gp from $s3
# This will create a new save-all frame, required by the runtime.
DELIVER_PENDING_EXCEPTION
END art_quick_generic_jni_trampoline