Add JNI trampoline for mips32.
This patch allows the browser to come up.
Change-Id: Icad9da868be76d6a08e615807fad8678ac0a110f
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index e878ef7..a445226 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -26,44 +26,48 @@
/* Deliver an exception pending on a thread */
.extern artDeliverPendingExceptionFromCode
+#define ARG_SLOT_SIZE 32 // space for a0-a3 plus 4 more words
+
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(kSaveAll)
- * Callee-save: $s0-$s8 + $gp + $ra, 11 total + 1 word padding + 4 open words for args
- * Clobbers $t0 and $gp
+ * Callee-save: $s0-$s8 + $gp + $ra, 11 total + 1 word for Method*
+ * Clobbers $t0 and $sp
+ * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
+ * Reserves FRAME_SIZE_SAVE_ALL_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack
*/
.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
- addiu $sp, $sp, -64
- .cfi_adjust_cfa_offset 64
+ addiu $sp, $sp, -48
+ .cfi_adjust_cfa_offset 48
// Ugly compile-time check, but we only have the preprocessor.
-#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 64)
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 48)
#error "SAVE_ALL_CALLEE_SAVE_FRAME(MIPS) size not as expected."
#endif
- sw $ra, 60($sp)
- .cfi_rel_offset 31, 60
- sw $s8, 56($sp)
- .cfi_rel_offset 30, 56
- sw $gp, 52($sp)
- .cfi_rel_offset 28, 52
- sw $s7, 48($sp)
- .cfi_rel_offset 23, 48
- sw $s6, 44($sp)
- .cfi_rel_offset 22, 44
- sw $s5, 40($sp)
- .cfi_rel_offset 21, 40
- sw $s4, 36($sp)
- .cfi_rel_offset 20, 36
- sw $s3, 32($sp)
- .cfi_rel_offset 19, 32
- sw $s2, 28($sp)
- .cfi_rel_offset 18, 28
- sw $s1, 24($sp)
- .cfi_rel_offset 17, 24
- sw $s0, 20($sp)
- .cfi_rel_offset 16, 20
- # 1 word for alignment, 4 open words for args $a0-$a3, bottom will hold Method*
+ sw $ra, 44($sp)
+ .cfi_rel_offset 31, 44
+ sw $s8, 40($sp)
+ .cfi_rel_offset 30, 40
+ sw $gp, 36($sp)
+ .cfi_rel_offset 28, 36
+ sw $s7, 32($sp)
+ .cfi_rel_offset 23, 32
+ sw $s6, 28($sp)
+ .cfi_rel_offset 22, 28
+ sw $s5, 24($sp)
+ .cfi_rel_offset 21, 24
+ sw $s4, 20($sp)
+ .cfi_rel_offset 20, 20
+ sw $s3, 16($sp)
+ .cfi_rel_offset 19, 16
+ sw $s2, 12($sp)
+ .cfi_rel_offset 18, 12
+ sw $s1, 8($sp)
+ .cfi_rel_offset 17, 8
+ sw $s0, 4($sp)
+ .cfi_rel_offset 16, 4
+ # 1 word for holding Method*
lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
lw $t0, 0($t0)
@@ -71,42 +75,47 @@
lw $t0, RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET($t0)
sw $t0, 0($sp) # Place Method* at bottom of stack.
sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
+ addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack
+ .cfi_adjust_cfa_offset ARG_SLOT_SIZE
.endm
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(kRefsOnly). Restoration assumes non-moving GC.
* Does not include rSUSPEND or rSELF
- * callee-save: $s2-$s8 + $gp + $ra, 9 total + 3 words padding + 4 open words for args
+ * callee-save: $s2-$s8 + $gp + $ra, 9 total + 2 words padding + 1 word to hold Method*
+ * Clobbers $t0 and $sp
+ * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
+ * Reserves FRAME_SIZE_REFS_ONLY_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack
*/
.macro SETUP_REFS_ONLY_CALLEE_SAVE_FRAME
- addiu $sp, $sp, -64
- .cfi_adjust_cfa_offset 64
+ addiu $sp, $sp, -48
+ .cfi_adjust_cfa_offset 48
// Ugly compile-time check, but we only have the preprocessor.
-#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 64)
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 48)
#error "REFS_ONLY_CALLEE_SAVE_FRAME(MIPS) size not as expected."
#endif
- sw $ra, 60($sp)
- .cfi_rel_offset 31, 60
- sw $s8, 56($sp)
- .cfi_rel_offset 30, 56
- sw $gp, 52($sp)
- .cfi_rel_offset 28, 52
- sw $s7, 48($sp)
- .cfi_rel_offset 23, 48
- sw $s6, 44($sp)
- .cfi_rel_offset 22, 44
- sw $s5, 40($sp)
- .cfi_rel_offset 21, 40
- sw $s4, 36($sp)
- .cfi_rel_offset 20, 36
- sw $s3, 32($sp)
- .cfi_rel_offset 19, 32
- sw $s2, 28($sp)
- .cfi_rel_offset 18, 28
- # 3 words for alignment and extra args, 4 open words for args $a0-$a3, bottom will hold Method*
+ sw $ra, 44($sp)
+ .cfi_rel_offset 31, 44
+ sw $s8, 40($sp)
+ .cfi_rel_offset 30, 40
+ sw $gp, 36($sp)
+ .cfi_rel_offset 28, 36
+ sw $s7, 32($sp)
+ .cfi_rel_offset 23, 32
+ sw $s6, 28($sp)
+ .cfi_rel_offset 22, 28
+ sw $s5, 24($sp)
+ .cfi_rel_offset 21, 24
+ sw $s4, 20($sp)
+ .cfi_rel_offset 20, 20
+ sw $s3, 16($sp)
+ .cfi_rel_offset 19, 16
+ sw $s2, 12($sp)
+ .cfi_rel_offset 18, 12
+ # 2 words for alignment and bottom word will hold Method*
lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
lw $t0, 0($t0)
@@ -114,61 +123,47 @@
lw $t0, RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET($t0)
sw $t0, 0($sp) # Place Method* at bottom of stack.
sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
+ addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack
+ .cfi_adjust_cfa_offset ARG_SLOT_SIZE
.endm
.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
- lw $ra, 60($sp)
+ addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack
+ .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
+ lw $ra, 44($sp)
.cfi_restore 31
- lw $s8, 56($sp)
+ lw $s8, 40($sp)
.cfi_restore 30
- lw $gp, 52($sp)
+ lw $gp, 36($sp)
.cfi_restore 28
- lw $s7, 48($sp)
+ lw $s7, 32($sp)
.cfi_restore 23
- lw $s6, 44($sp)
+ lw $s6, 28($sp)
.cfi_restore 22
- lw $s5, 40($sp)
+ lw $s5, 24($sp)
.cfi_restore 21
- lw $s4, 36($sp)
+ lw $s4, 20($sp)
.cfi_restore 20
- lw $s3, 32($sp)
+ lw $s3, 16($sp)
.cfi_restore 19
- lw $s2, 28($sp)
+ lw $s2, 12($sp)
.cfi_restore 18
- addiu $sp, $sp, 64
- .cfi_adjust_cfa_offset -64
+ addiu $sp, $sp, 48
+ .cfi_adjust_cfa_offset -48
.endm
.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
- lw $ra, 60($sp)
- .cfi_restore 31
- lw $s8, 56($sp)
- .cfi_restore 30
- lw $gp, 52($sp)
- .cfi_restore 28
- lw $s7, 48($sp)
- .cfi_restore 23
- lw $s6, 44($sp)
- .cfi_restore 22
- lw $s5, 40($sp)
- .cfi_restore 21
- lw $s4, 36($sp)
- .cfi_restore 20
- lw $s3, 32($sp)
- .cfi_restore 19
- lw $s2, 28($sp)
- .cfi_restore 18
+ RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
jr $ra
- addiu $sp, $sp, 64
- .cfi_adjust_cfa_offset -64
+ nop
.endm
/*
* Macro that sets up the callee save frame to conform with
- * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC.
+ * Runtime::CreateCalleeSaveMethod(kRefsAndArgs).
* callee-save: $a1-$a3, $s2-$s8 + $gp + $ra, 12 total + 3 words padding + method*
*/
-.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
+.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
addiu $sp, $sp, -64
.cfi_adjust_cfa_offset 64
@@ -202,16 +197,48 @@
sw $a1, 4($sp)
.cfi_rel_offset 5, 4
# bottom will hold Method*
+.endm
+ /*
+ * Macro that sets up the callee save frame to conform with
+ * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC.
+ * callee-save: $a1-$a3, $s2-$s8 + $gp + $ra, 12 total + 3 words padding + method*
+ * Clobbers $t0 and $sp
+ * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
+ * Reserves FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack
+ */
+.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
+ SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
lw $t0, 0($t0)
THIS_LOAD_REQUIRES_READ_BARRIER
lw $t0, RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET($t0)
sw $t0, 0($sp) # Place Method* at bottom of stack.
sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
+ addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack
+ .cfi_adjust_cfa_offset ARG_SLOT_SIZE
+.endm
+
+ /*
+ * Macro that sets up the callee save frame to conform with
+ * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC.
+ * callee-save: $a1-$a3, $s2-$s8 + $gp + $ra, 12 total + 3 words padding + method*
+ * Clobbers $sp
+ * Use $a0 as the Method* and loads it into bottom of stack.
+ * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
+ * Reserves FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack
+ */
+.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
+ SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
+ sw $a0, 0($sp) # Place Method* at bottom of stack.
+ sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
+ addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack
+ .cfi_adjust_cfa_offset ARG_SLOT_SIZE
.endm
.macro RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
+ addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack
+ .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
lw $ra, 60($sp)
.cfi_restore 31
lw $s8, 56($sp)
@@ -444,21 +471,15 @@
.extern \cxx_name
ENTRY \c_name
SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC
- lw $a2, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE($sp) # pass caller Method*
- move $t0, $sp # save $sp
- addiu $sp, $sp, -32 # make space for extra args
- .cfi_adjust_cfa_offset 32
+ lw $a2, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE+ARG_SLOT_SIZE($sp) # pass caller Method*
+ addiu $t0, $sp, ARG_SLOT_SIZE # save $sp (remove arg slots)
move $a3, rSELF # pass Thread::Current
- .cfi_rel_offset 28, 12
jal \cxx_name # (method_idx, this, caller, Thread*, $sp)
sw $t0, 16($sp) # pass $sp
- addiu $sp, $sp, 32 # release out args
- .cfi_adjust_cfa_offset -32
move $a0, $v0 # save target Method*
- move $t9, $v1 # save $v0->code_
RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
beqz $v0, 1f
- nop
+ move $t9, $v1 # save $v0->code_
jr $t9
nop
1:
@@ -500,10 +521,10 @@
.cfi_def_cfa_register 30
move $s1, $a3 # move managed thread pointer into s1
addiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset s0 to suspend check interval
- addiu $t0, $a2, 16 # create space for method pointer in frame
- srl $t0, $t0, 4 # shift the frame size right 4
- sll $t0, $t0, 4 # shift the frame size left 4 to align to 16 bytes
- subu $sp, $sp, $t0 # reserve stack space for argument array
+ addiu $t0, $a2, 4 # create space for method pointer in frame.
+ subu $t0, $sp, $t0 # reserve & align *stack* to 16 bytes:
+ srl $t0, $t0, 4 # native calling convention only aligns to 8B,
+ sll $sp, $t0, 4 # so we have to ensure ART 16B alignment ourselves.
addiu $a0, $sp, 4 # pass stack pointer + method ptr as dest for memcpy
jal memcpy # (dest, src, bytes)
addiu $sp, $sp, -16 # make space for argument slots for memcpy
@@ -548,8 +569,8 @@
*/
.extern artHandleFillArrayDataFromCode
ENTRY art_quick_handle_fill_data
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
jal artHandleFillArrayDataFromCode # (payload offset, Array*, method, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -562,7 +583,7 @@
ENTRY art_quick_lock_object
beqz $a0, .Lart_quick_throw_null_pointer_exception_gp_set
nop
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case we block
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case we block
jal artLockObjectFromCode # (Object* obj, Thread*)
move $a1, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -575,7 +596,7 @@
ENTRY art_quick_unlock_object
beqz $a0, .Lart_quick_throw_null_pointer_exception_gp_set
nop
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
jal artUnlockObjectFromCode # (Object* obj, Thread*)
move $a1, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -594,7 +615,8 @@
sw $a1, 4($sp)
sw $a0, 0($sp)
jal artIsAssignableFromCode
- nop
+ addiu $sp, $sp, -16 # reserve argument slots on the stack
+ addiu $sp, $sp, 16
beqz $v0, .Lthrow_class_cast_exception
lw $ra, 12($sp)
jr $ra
@@ -670,7 +692,8 @@
move $a1, $t1
move $a0, $t0
jal artIsAssignableFromCode # (Class*, Class*)
- nop
+ addiu $sp, $sp, -16 # reserve argument slots on the stack
+ addiu $sp, $sp, 16
lw $ra, 28($sp)
lw $t9, 12($sp)
lw $a2, 8($sp)
@@ -694,7 +717,7 @@
*/
.extern artInitializeStaticStorageFromCode
ENTRY art_quick_initialize_static_storage
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
# artInitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer, Thread*)
jal artInitializeStaticStorageFromCode
move $a2, rSELF # pass Thread::Current
@@ -706,7 +729,7 @@
*/
.extern artInitializeTypeFromCode
ENTRY art_quick_initialize_type
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
# artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*)
jal artInitializeTypeFromCode
move $a2, rSELF # pass Thread::Current
@@ -719,7 +742,7 @@
*/
.extern artInitializeTypeAndVerifyAccessFromCode
ENTRY art_quick_initialize_type_and_verify_access
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
# artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*)
jal artInitializeTypeAndVerifyAccessFromCode
move $a2, rSELF # pass Thread::Current
@@ -730,8 +753,8 @@
*/
.extern artGetBooleanStaticFromCode
ENTRY art_quick_get_boolean_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetBooleanStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -741,8 +764,8 @@
*/
.extern artGetByteStaticFromCode
ENTRY art_quick_get_byte_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetByteStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -753,8 +776,8 @@
*/
.extern artGetCharStaticFromCode
ENTRY art_quick_get_char_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetCharStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -764,8 +787,8 @@
*/
.extern artGetShortStaticFromCode
ENTRY art_quick_get_short_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetShortStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -776,8 +799,8 @@
*/
.extern artGet32StaticFromCode
ENTRY art_quick_get32_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGet32StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -788,8 +811,8 @@
*/
.extern artGet64StaticFromCode
ENTRY art_quick_get64_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGet64StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -800,8 +823,8 @@
*/
.extern artGetObjStaticFromCode
ENTRY art_quick_get_obj_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetObjStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
move $a2, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -812,8 +835,8 @@
*/
.extern artGetBooleanInstanceFromCode
ENTRY art_quick_get_boolean_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetBooleanInstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -823,8 +846,8 @@
*/
.extern artGetByteInstanceFromCode
ENTRY art_quick_get_byte_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetByteInstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -835,8 +858,8 @@
*/
.extern artGetCharInstanceFromCode
ENTRY art_quick_get_char_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetCharInstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -846,9 +869,9 @@
*/
.extern artGetShortInstanceFromCode
ENTRY art_quick_get_short_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
- jal artGetShortInstanceFromCode # (field_idx, Object*, referrer, Thread*)
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ jal artGetShortInstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
END art_quick_get_short_instance
@@ -858,11 +881,10 @@
*/
.extern artGet32InstanceFromCode
ENTRY art_quick_get32_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
- jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
- sw $sp, 16($sp) # pass $sp
RETURN_IF_NO_EXCEPTION
END art_quick_get32_instance
@@ -871,11 +893,10 @@
*/
.extern artGet64InstanceFromCode
ENTRY art_quick_get64_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
- jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
- sw $sp, 16($sp) # pass $sp
RETURN_IF_NO_EXCEPTION
END art_quick_get64_instance
@@ -884,8 +905,8 @@
*/
.extern artGetObjInstanceFromCode
ENTRY art_quick_get_obj_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artGetObjInstanceFromCode # (field_idx, Object*, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_NO_EXCEPTION
@@ -896,8 +917,8 @@
*/
.extern artSet8StaticFromCode
ENTRY art_quick_set8_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet8StaticFromCode # (field_idx, new_val, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -908,8 +929,8 @@
*/
.extern artSet16StaticFromCode
ENTRY art_quick_set16_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet16StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp)
move $a3, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -920,8 +941,8 @@
*/
.extern artSet32StaticFromCode
ENTRY art_quick_set32_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet32StaticFromCode # (field_idx, new_val, referrer, Thread*)
move $a3, rSELF # pass Thread::Current
RETURN_IF_ZERO
@@ -932,8 +953,8 @@
*/
.extern artSet64StaticFromCode
ENTRY art_quick_set64_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a1, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet64StaticFromCode # (field_idx, referrer, new_val, Thread*)
sw rSELF, 16($sp) # pass Thread::Current
RETURN_IF_ZERO
@@ -944,10 +965,10 @@
*/
.extern artSetObjStaticFromCode
ENTRY art_quick_set_obj_static
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
- jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*)
+ lw $a2, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
move $a3, rSELF # pass Thread::Current
+ jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*)
RETURN_IF_ZERO
END art_quick_set_obj_static
@@ -956,9 +977,9 @@
*/
.extern artSet8InstanceFromCode
ENTRY art_quick_set8_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
- jal artSet8InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
+ lw $a3, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ jal artSet8InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
sw rSELF, 16($sp) # pass Thread::Current
RETURN_IF_ZERO
END art_quick_set8_instance
@@ -968,8 +989,8 @@
*/
.extern artSet16InstanceFromCode
ENTRY art_quick_set16_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a3, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet16InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
sw rSELF, 16($sp) # pass Thread::Current
RETURN_IF_ZERO
@@ -980,8 +1001,8 @@
*/
.extern artSet32InstanceFromCode
ENTRY art_quick_set32_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a3, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSet32InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
sw rSELF, 16($sp) # pass Thread::Current
RETURN_IF_ZERO
@@ -992,11 +1013,11 @@
*/
.extern artSet64InstanceFromCode
ENTRY art_quick_set64_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $t0, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # load referrer's Method*
+ lw $t1, 0($sp) # load referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
sw rSELF, 20($sp) # pass Thread::Current
jal artSet64InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
- sw $t0, 16($sp) # pass referrer's Method*
+ sw $t1, 16($sp) # pass referrer's Method*
RETURN_IF_ZERO
END art_quick_set64_instance
@@ -1005,8 +1026,8 @@
*/
.extern artSetObjInstanceFromCode
ENTRY art_quick_set_obj_instance
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
- lw $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
+ lw $a3, 0($sp) # pass referrer's Method*
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal artSetObjInstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
sw rSELF, 16($sp) # pass Thread::Current
RETURN_IF_ZERO
@@ -1020,7 +1041,7 @@
*/
.extern artResolveStringFromCode
ENTRY art_quick_resolve_string
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
# artResolveStringFromCode(Method* referrer, uint32_t string_idx, Thread*)
jal artResolveStringFromCode
move $a2, rSELF # pass Thread::Current
@@ -1032,7 +1053,7 @@
.macro TWO_ARG_DOWNCALL name, entrypoint, return
.extern \entrypoint
ENTRY \name
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal \entrypoint
move $a2, rSELF # pass Thread::Current
\return
@@ -1042,7 +1063,7 @@
.macro THREE_ARG_DOWNCALL name, entrypoint, return
.extern \entrypoint
ENTRY \name
- SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jal \entrypoint
move $a3, rSELF # pass Thread::Current
\return
@@ -1075,13 +1096,12 @@
*/
.extern artQuickProxyInvokeHandler
ENTRY art_quick_proxy_invoke_handler
- SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
- sw $a0, 0($sp) # place proxy method at bottom of frame
- move $a2, rSELF # pass Thread::Current
+ SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
+ move $a2, rSELF # pass Thread::Current
jal artQuickProxyInvokeHandler # (Method* proxy method, receiver, Thread*, SP)
- move $a3, $sp # pass $sp
+ addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots)
lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
- RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
+ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
bnez $t0, 1f
mtc1 $v0, $f0 # place return value to FP return value
jr $ra
@@ -1107,11 +1127,11 @@
.extern artQuickResolutionTrampoline
ENTRY art_quick_resolution_trampoline
SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
- move $a2, rSELF # pass Thread::Current
+ move $a2, rSELF # pass Thread::Current
jal artQuickResolutionTrampoline # (Method* called, receiver, Thread*, SP)
- move $a3, $sp # pass $sp
+ addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots)
beqz $v0, 1f
- lw $a0, 0($sp) # load resolved method to $a0
+ lw $a0, ARG_SLOT_SIZE($sp) # load resolved method to $a0
RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
move $t9, $v0 # code pointer must be in $t9 to generate the global pointer
jr $v0 # tail call to method
@@ -1121,16 +1141,75 @@
DELIVER_PENDING_EXCEPTION
END art_quick_resolution_trampoline
-UNIMPLEMENTED art_quick_generic_jni_trampoline
+ .extern artQuickGenericJniTrampoline
+ .extern artQuickGenericJniEndTrampoline
+ENTRY art_quick_generic_jni_trampoline
+ SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
+ move $s8, $sp # save $sp to $s8
+ move $s3, $gp # save $gp to $s3
+
+ # prepare for call to artQuickGenericJniTrampoline(Thread*, SP)
+ move $a0, rSELF # pass Thread::Current
+ addiu $a1, $sp, ARG_SLOT_SIZE # save $sp (remove arg slots)
+ jal artQuickGenericJniTrampoline # (Thread*, SP)
+ addiu $sp, $sp, -5120 # reserve space on the stack
+
+ # The C call will have registered the complete save-frame on success.
+ # The result of the call is:
+ # v0: ptr to native code, 0 on error.
+ # v1: ptr to the bottom of the used area of the alloca, can restore stack till here.
+ beq $v0, $zero, 1f # check entry error
+ move $t9, $v0 # save the code ptr
+ move $sp, $v1 # release part of the alloca
+
+ # Load parameters from stack into registers
+ lw $a0, 0($sp)
+ lw $a1, 4($sp)
+ lw $a2, 8($sp)
+
+ # Load FPRs the same as GPRs. Look at BuildNativeCallFrameStateMachine.
+ jalr $t9 # native call
+ lw $a3, 12($sp)
+ addiu $sp, $sp, 16 # remove arg slots
+
+ move $gp, $s3 # restore $gp from $s3
+
+ # result sign extension is handled in C code
+ # prepare for call to artQuickGenericJniEndTrampoline(Thread*, result, result_f)
+ move $a0, rSELF # pass Thread::Current
+ move $a2, $v0 # pass result
+ move $a3, $v1
+ addiu $sp, $sp, -24 # reserve arg slots
+ jal artQuickGenericJniEndTrampoline
+ s.d $f0, 16($sp) # pass result_f
+ addiu $sp, $sp, 24 # remove arg slots
+
+ lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
+ bne $t0, $zero, 2f # check for pending exceptions
+ move $sp, $s8 # tear down the alloca
+
+ # tear dpown the callee-save frame
+ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
+
+ mtc1 $v0, $f0 # place return value to FP return value
+ jr $ra
+ mtc1 $v1, $f1 # place return value to FP return value
+
+1:
+ move $sp, $s8 # tear down the alloca
+2:
+ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
+ DELIVER_PENDING_EXCEPTION
+END art_quick_generic_jni_trampoline
.extern artQuickToInterpreterBridge
ENTRY art_quick_to_interpreter_bridge
SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
- move $a1, rSELF # pass Thread::Current
- jal artQuickToInterpreterBridge # (Method* method, Thread*, SP)
- move $a2, $sp # pass $sp
+ move $a1, rSELF # pass Thread::Current
+ jal artQuickToInterpreterBridge # (Method* method, Thread*, SP)
+ addiu $a2, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots)
lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
- RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
+ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
bnez $t0, 1f
mtc1 $v0, $f0 # place return value to FP return value
jr $ra
@@ -1146,17 +1225,12 @@
.extern artInstrumentationMethodExitFromCode
ENTRY art_quick_instrumentation_entry
SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
- move $t0, $sp # remember bottom of caller's frame
- addiu $sp, $sp, -32 # space for saved a0, pad (2 words), arguments (4 words)
- .cfi_adjust_cfa_offset 32
- sw $a0, 28($sp) # save arg0
+ sw $a0, 28($sp) # save arg0 in free arg slot
move $a3, $ra # pass $ra
jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, LR)
move $a2, rSELF # pass Thread::Current
move $t9, $v0 # $t9 holds reference to code
- lw $a0, 28($sp) # restore arg0
- addiu $sp, $sp, 32 # remove args
- .cfi_adjust_cfa_offset -32
+ lw $a0, 28($sp) # restore arg0 from free arg slot
RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
jalr $t9 # call method
nop
@@ -1168,32 +1242,33 @@
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_REFS_ONLY_CALLEE_SAVE_FRAME
- move $t0, $sp # remember bottom of caller's frame
- addiu $sp, $sp, -48 # save return values and set up args
- .cfi_adjust_cfa_offset 48
- sw $v0, 32($sp)
+
+ addiu $sp, $sp, -16 # allocate temp storage on the stack
+ .cfi_adjust_cfa_offset 16
+ sw $v0, 12($sp)
.cfi_rel_offset 2, 32
- sw $v1, 36($sp)
+ sw $v1, 8($sp)
.cfi_rel_offset 3, 36
- s.s $f0, 40($sp)
- s.s $f1, 44($sp)
+ s.s $f0, 4($sp)
+ s.s $f1, 0($sp)
+ SETUP_REFS_ONLY_CALLEE_SAVE_FRAME
s.s $f0, 16($sp) # pass fpr result
s.s $f1, 20($sp)
move $a2, $v0 # pass gpr result
move $a3, $v1
- move $a1, $t0 # pass $sp
+ addiu $a1, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots)
jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res, fpr_res)
move $a0, rSELF # pass Thread::Current
move $t0, $v0 # set aside returned link register
move $ra, $v1 # set link register for deoptimization
- lw $v0, 32($sp) # restore return values
- lw $v1, 36($sp)
- l.s $f0, 40($sp)
- l.s $f1, 44($sp)
+ addiu $sp, $sp, ARG_SLOT_SIZE+FRAME_SIZE_REFS_ONLY_CALLEE_SAVE # args slot + refs_only callee save frame
+ lw $v0, 12($sp) # restore return values
+ lw $v1, 8($sp)
+ l.s $f0, 4($sp)
+ l.s $f1, 0($sp)
jr $t0 # return
- addiu $sp, $sp, 112 # 48 bytes of args + 64 bytes of callee save frame
- .cfi_adjust_cfa_offset -112
+ addiu $sp, $sp, 16 # remove temp storage from stack
+ .cfi_adjust_cfa_offset -16
END art_quick_instrumentation_exit
/*