Save all registers in native to Java stubs.
This will make things more friendly when experimenting with the
number of callee saves in optimizing.
Change-Id: Iefd9a2da329a420eb69fc2fa9e91c06bbda30cdb
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 0ae54dc..66ea3ce 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -379,12 +379,17 @@
* +-------------------------+
*/
ENTRY art_quick_invoke_stub_internal
- push {r4, r9, r11, lr} @ spill regs
+ push {r4, r5, r6, r7, r8, r9, r10, r11, lr} @ spill regs
.cfi_adjust_cfa_offset 16
.cfi_rel_offset r4, 0
- .cfi_rel_offset r9, 4
- .cfi_rel_offset r11, 8
- .cfi_rel_offset lr, 12
+ .cfi_rel_offset r5, 4
+ .cfi_rel_offset r6, 8
+ .cfi_rel_offset r7, 12
+ .cfi_rel_offset r8, 16
+ .cfi_rel_offset r9, 20
+ .cfi_rel_offset r10, 24
+ .cfi_rel_offset r11, 28
+ .cfi_rel_offset lr, 32
mov r11, sp @ save the stack pointer
.cfi_def_cfa_register r11
@@ -401,10 +406,10 @@
mov ip, #0 @ set ip to 0
str ip, [sp] @ store NULL for method* at bottom of frame
- ldr ip, [r11, #28] @ load fp register argument array pointer
+ ldr ip, [r11, #48] @ load fp register argument array pointer
vldm ip, {s0-s15} @ copy s0 - s15
- ldr ip, [r11, #24] @ load core register argument array pointer
+ ldr ip, [r11, #44] @ load core register argument array pointer
mov r0, r4 @ restore method*
add ip, ip, #4 @ skip r0
ldm ip, {r1-r3} @ copy r1 - r3
@@ -419,14 +424,14 @@
mov sp, r11 @ restore the stack pointer
.cfi_def_cfa_register sp
- ldr r4, [sp, #20] @ load result_is_float
- ldr r9, [sp, #16] @ load the result pointer
+ ldr r4, [sp, #40] @ load result_is_float
+ ldr r9, [sp, #36] @ load the result pointer
cmp r4, #0
ite eq
strdeq r0, [r9] @ store r0/r1 into result pointer
vstrne d0, [r9] @ store s0-s1/d0 into result pointer
- pop {r4, r9, r11, pc} @ restore spill regs
+ pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} @ restore spill regs
END art_quick_invoke_stub_internal
/*
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 4415935..6047bb0 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -499,7 +499,7 @@
.macro INVOKE_STUB_CREATE_FRAME
-SAVE_SIZE=6*8 // x4, x5, xSUSPEND, SP, LR & FP saved.
+SAVE_SIZE=15*8 // x4, x5, x20, x21, x22, x23, x24, x25, x26, x27, x28, xSUSPEND, SP, LR, FP saved.
SAVE_SIZE_AND_METHOD=SAVE_SIZE+STACK_REFERENCE_SIZE
@@ -515,6 +515,25 @@
.cfi_def_cfa_register x10 // before this.
.cfi_adjust_cfa_offset SAVE_SIZE
+ str x28, [x10, #112]
+ .cfi_rel_offset x28, 112
+
+ stp x26, x27, [x10, #96]
+ .cfi_rel_offset x26, 96
+ .cfi_rel_offset x27, 104
+
+ stp x24, x25, [x10, #80]
+ .cfi_rel_offset x24, 80
+ .cfi_rel_offset x25, 88
+
+ stp x22, x23, [x10, #64]
+ .cfi_rel_offset x22, 64
+ .cfi_rel_offset x23, 72
+
+ stp x20, x21, [x10, #48]
+ .cfi_rel_offset x20, 48
+ .cfi_rel_offset x21, 56
+
stp x9, xSUSPEND, [x10, #32] // Save old stack pointer and xSUSPEND
.cfi_rel_offset sp, 32
.cfi_rel_offset x19, 40
@@ -573,6 +592,25 @@
.cfi_restore x4
.cfi_restore x5
+ ldr x28, [xFP, #112]
+ .cfi_restore x28
+
+ ldp x26, x27, [xFP, #96]
+ .cfi_restore x26
+ .cfi_restore x27
+
+ ldp x24, x25, [xFP, #80]
+ .cfi_restore x24
+ .cfi_restore x25
+
+ ldp x22, x23, [xFP, #64]
+ .cfi_restore x22
+ .cfi_restore x23
+
+ ldp x20, x21, [xFP, #48]
+ .cfi_restore x20
+ .cfi_restore x21
+
// Store result (w0/x0/s0/d0) appropriately, depending on resultType.
ldrb w10, [x5]
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 0bfa1ce..302b9f8 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -297,28 +297,34 @@
DEFINE_FUNCTION art_quick_invoke_stub
PUSH ebp // save ebp
PUSH ebx // save ebx
+ PUSH esi // save esi
+ PUSH edi // save edi
mov %esp, %ebp // copy value of stack pointer into base pointer
CFI_DEF_CFA_REGISTER(ebp)
- mov 20(%ebp), %ebx // get arg array size
- addl LITERAL(28), %ebx // reserve space for return addr, method*, ebx, and ebp in frame
- andl LITERAL(0xFFFFFFF0), %ebx // align frame size to 16 bytes
- subl LITERAL(12), %ebx // remove space for return address, ebx, and ebp
+ mov 28(%ebp), %ebx // get arg array size
+ // reserve space for return addr, method*, ebx, ebp, esi, and edi in frame
+ addl LITERAL(36), %ebx
+ // align frame size to 16 bytes
+ andl LITERAL(0xFFFFFFF0), %ebx
+ subl LITERAL(20), %ebx // remove space for return address, ebx, ebp, esi and edi
subl %ebx, %esp // reserve stack space for argument array
SETUP_GOT_NOSAVE ebx // clobbers ebx (harmless here)
lea 4(%esp), %eax // use stack pointer + method ptr as dest for memcpy
- pushl 20(%ebp) // push size of region to memcpy
- pushl 16(%ebp) // push arg array as source of memcpy
+ pushl 28(%ebp) // push size of region to memcpy
+ pushl 24(%ebp) // push arg array as source of memcpy
pushl %eax // push stack pointer as destination of memcpy
call PLT_SYMBOL(memcpy) // (void*, const void*, size_t)
addl LITERAL(12), %esp // pop arguments to memcpy
movl LITERAL(0), (%esp) // store NULL for method*
- mov 12(%ebp), %eax // move method pointer into eax
+ mov 20(%ebp), %eax // move method pointer into eax
mov 4(%esp), %ecx // copy arg1 into ecx
mov 8(%esp), %edx // copy arg2 into edx
mov 12(%esp), %ebx // copy arg3 into ebx
call *MIRROR_ART_METHOD_QUICK_CODE_OFFSET_32(%eax) // call the method
mov %ebp, %esp // restore stack pointer
CFI_DEF_CFA_REGISTER(esp)
+ POP edi // pop edi
+ POP esi // pop esi
POP ebx // pop ebx
POP ebp // pop ebp
mov 20(%esp), %ecx // get result pointer
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 7f85ab7..5ae65db 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -487,15 +487,21 @@
PUSH rbp // Save rbp.
PUSH r8 // Save r8/result*.
PUSH r9 // Save r9/shorty*.
+ PUSH rbx // Save native callee save rbx
+ PUSH r12 // Save native callee save r12
+ PUSH r13 // Save native callee save r13
+ PUSH r14 // Save native callee save r14
+ PUSH r15 // Save native callee save r15
movq %rsp, %rbp // Copy value of stack pointer into base pointer.
CFI_DEF_CFA_REGISTER(rbp)
movl %edx, %r10d
- addl LITERAL(60), %edx // Reserve space for return addr, StackReference<method>, rbp,
- // r8 and r9 in frame.
- andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
- subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9.
- subq %rdx, %rsp // Reserve stack space for argument array.
+ addl LITERAL(100), %edx // Reserve space for return addr, StackReference<method>, rbp,
+ // r8, r9, rbx, r12, r13, r14, and r15 in frame.
+ andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
+ subl LITERAL(72), %edx // Remove space for return address, rbp, r8, r9, rbx, r12,
+ // r13, r14, and r15
+ subq %rdx, %rsp // Reserve stack space for argument array.
#if (STACK_REFERENCE_SIZE != 4)
#error "STACK_REFERENCE_SIZE(X86_64) size not as expected."
@@ -503,15 +509,15 @@
movl LITERAL(0), (%rsp) // Store NULL for method*
movl %r10d, %ecx // Place size of args in rcx.
- movq %rdi, %rax // RAX := method to be called
- movq %rsi, %r11 // R11 := arg_array
- leaq 4(%rsp), %rdi // Rdi is pointing just above the StackReference<method> in the
+ movq %rdi, %rax // rax := method to be called
+ movq %rsi, %r11 // r11 := arg_array
+ leaq 4(%rsp), %rdi // rdi is pointing just above the StackReference<method> in the
// stack arguments.
// Copy arg array into stack.
rep movsb // while (rcx--) { *rdi++ = *rsi++ }
- leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character
- movq %rax, %rdi // RDI := method to be called
- movl (%r11), %esi // RSI := this pointer
+ leaq 1(%r9), %r10 // r10 := shorty + 1 ; ie skip return arg character
+ movq %rax, %rdi // rdi := method to be called
+ movl (%r11), %esi // rsi := this pointer
addq LITERAL(4), %r11 // arg_array++
LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished
LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished
@@ -520,8 +526,12 @@
.Lgpr_setup_finished:
call *MIRROR_ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
movq %rbp, %rsp // Restore stack pointer.
- CFI_DEF_CFA_REGISTER(rsp)
- POP r9 // Pop r9 - shorty*.
+ POP r15 // Pop r15
+ POP r14 // Pop r14
+ POP r13 // Pop r13
+ POP r12 // Pop r12
+ POP rbx // Pop rbx
+ POP r9 // Pop r9 - shorty*
POP r8 // Pop r8 - result*.
POP rbp // Pop rbp
cmpb LITERAL(68), (%r9) // Test if result type char == 'D'.
@@ -531,10 +541,10 @@
movq %rax, (%r8) // Store the result assuming its a long, int or Object*
ret
.Lreturn_double_quick:
- movsd %xmm0, (%r8) // Store the double floating point result.
+ movsd %xmm0, (%r8) // Store the double floating point result.
ret
.Lreturn_float_quick:
- movss %xmm0, (%r8) // Store the floating point result.
+ movss %xmm0, (%r8) // Store the floating point result.
ret
#endif // __APPLE__
END_FUNCTION art_quick_invoke_stub
@@ -571,30 +581,36 @@
PUSH rbp // Save rbp.
PUSH r8 // Save r8/result*.
PUSH r9 // Save r9/shorty*.
+ PUSH rbx // Save rbx
+ PUSH r12 // Save r12
+ PUSH r13 // Save r13
+ PUSH r14 // Save r14
+ PUSH r15 // Save r15
movq %rsp, %rbp // Copy value of stack pointer into base pointer.
CFI_DEF_CFA_REGISTER(rbp)
movl %edx, %r10d
- addl LITERAL(60), %edx // Reserve space for return addr, StackReference<method>, rbp,
- // r8 and r9 in frame.
- andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
- subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9.
- subq %rdx, %rsp // Reserve stack space for argument array.
+ addl LITERAL(100), %edx // Reserve space for return addr, StackReference<method>, rbp,
+ // r8, r9, r12, r13, r14, and r15 in frame.
+ andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
+ subl LITERAL(72), %edx // Remove space for return address, rbp, r8, r9, rbx, r12,
+ // r13, r14, and r15.
+ subq %rdx, %rsp // Reserve stack space for argument array.
#if (STACK_REFERENCE_SIZE != 4)
#error "STACK_REFERENCE_SIZE(X86_64) size not as expected."
#endif
- movl LITERAL(0), (%rsp) // Store NULL for method*
+ movl LITERAL(0), (%rsp) // Store NULL for method*
- movl %r10d, %ecx // Place size of args in rcx.
- movq %rdi, %rax // RAX := method to be called
- movq %rsi, %r11 // R11 := arg_array
- leaq 4(%rsp), %rdi // Rdi is pointing just above the StackReference<method> in the
- // stack arguments.
+ movl %r10d, %ecx // Place size of args in rcx.
+ movq %rdi, %rax // rax := method to be called
+ movq %rsi, %r11 // r11 := arg_array
+ leaq 4(%rsp), %rdi // rdi is pointing just above the StackReference<method> in the
+ // stack arguments.
// Copy arg array into stack.
- rep movsb // while (rcx--) { *rdi++ = *rsi++ }
- leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character
- movq %rax, %rdi // RDI := method to be called
+ rep movsb // while (rcx--) { *rdi++ = *rsi++ }
+ leaq 1(%r9), %r10 // r10 := shorty + 1 ; ie skip return arg character
+ movq %rax, %rdi // rdi := method to be called
LOOP_OVER_SHORTY_LOADING_GPRS rsi, esi, .Lgpr_setup_finished2
LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished2
LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished2
@@ -602,22 +618,26 @@
LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, .Lgpr_setup_finished2
.Lgpr_setup_finished2:
call *MIRROR_ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
- movq %rbp, %rsp // Restore stack pointer.
- CFI_DEF_CFA_REGISTER(rsp)
- POP r9 // Pop r9 - shorty*.
- POP r8 // Pop r8 - result*.
- POP rbp // Pop rbp
- cmpb LITERAL(68), (%r9) // Test if result type char == 'D'.
+ movq %rbp, %rsp // Restore stack pointer.
+ POP r15 // Pop r15
+ POP r14 // Pop r14
+ POP r13 // Pop r13
+ POP r12 // Pop r12
+ POP rbx // Pop rbx
+ POP r9 // Pop r9 - shorty*.
+ POP r8 // Pop r8 - result*.
+ POP rbp // Pop rbp
+ cmpb LITERAL(68), (%r9) // Test if result type char == 'D'.
je .Lreturn_double_quick2
- cmpb LITERAL(70), (%r9) // Test if result type char == 'F'.
+ cmpb LITERAL(70), (%r9) // Test if result type char == 'F'.
je .Lreturn_float_quick2
- movq %rax, (%r8) // Store the result assuming its a long, int or Object*
+ movq %rax, (%r8) // Store the result assuming its a long, int or Object*
ret
.Lreturn_double_quick2:
- movsd %xmm0, (%r8) // Store the double floating point result.
+ movsd %xmm0, (%r8) // Store the double floating point result.
ret
.Lreturn_float_quick2:
- movss %xmm0, (%r8) // Store the floating point result.
+ movss %xmm0, (%r8) // Store the floating point result.
ret
#endif // __APPLE__
END_FUNCTION art_quick_invoke_static_stub