Revert "Revert "Use implicit null checks inside try blocks.""
Fix implicit checks in try blocks to emit stack maps.
Fix arm64 null expection from signal entrypoint to call
the runtime handler instead or simply jumping there.
On Nexus 9, AOSP ToT, the boot.oat size reduction is
prebuilt multi-part boot image:
- 32-bit boot.oat: -448KiB (-1.3%)
- 64-bit boot.oat: -528KiB (-1.2%)
on-device built single boot image:
- 32-bit boot.oat: -448KiB (-1.4%)
- 64-bit boot.oat: -528KiB (-1.3%)
Note that the oat files no longer contain dex files which
have been moved to vdex, so the percentages are not directly
comparable with the those reported in the original commit.
Test: Run ART test suite including gc-stress on host and Nexus 9.
Bug: 30212852
Bug: 31468464
This reverts commit 0719b5b9b458cb3eb9f0823f0dacdfe1a71214dd.
Change-Id: If8a9da8c11adf2aad203e93b6684ce16ed776285
diff --git a/runtime/arch/x86/asm_support_x86.S b/runtime/arch/x86/asm_support_x86.S
index 3e47209..14b01c5 100644
--- a/runtime/arch/x86/asm_support_x86.S
+++ b/runtime/arch/x86/asm_support_x86.S
@@ -114,7 +114,7 @@
.balign 16
END_MACRO
-MACRO1(DEFINE_FUNCTION, c_name)
+MACRO2(DEFINE_FUNCTION_CUSTOM_CFA, c_name, cfa_offset)
FUNCTION_TYPE(SYMBOL(\c_name))
ASM_HIDDEN CALLVAR(c_name)
.globl CALLVAR(c_name)
@@ -122,7 +122,11 @@
CALLVAR(c_name):
CFI_STARTPROC
// Ensure we get a sane starting CFA.
- CFI_DEF_CFA(esp, 4)
+ CFI_DEF_CFA(esp, RAW_VAR(cfa_offset))
+END_MACRO
+
+MACRO1(DEFINE_FUNCTION, c_name)
+ DEFINE_FUNCTION_CUSTOM_CFA RAW_VAR(c_name), __SIZEOF_POINTER__
END_MACRO
MACRO1(END_FUNCTION, c_name)
diff --git a/runtime/arch/x86/fault_handler_x86.cc b/runtime/arch/x86/fault_handler_x86.cc
index c7af249..a4d6bb4 100644
--- a/runtime/arch/x86/fault_handler_x86.cc
+++ b/runtime/arch/x86/fault_handler_x86.cc
@@ -325,21 +325,15 @@
// next instruction (this instruction + instruction size). The return address
// is on the stack at the top address of the current frame.
- // Push the return address onto the stack.
+ // Push the return address and fault address onto the stack.
uintptr_t retaddr = reinterpret_cast<uintptr_t>(pc + instr_size);
- uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - sizeof(uintptr_t));
- *next_sp = retaddr;
+ uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - 2 * sizeof(uintptr_t));
+ next_sp[1] = retaddr;
+ next_sp[0] = reinterpret_cast<uintptr_t>(sig->si_addr);
uc->CTX_ESP = reinterpret_cast<uintptr_t>(next_sp);
uc->CTX_EIP = reinterpret_cast<uintptr_t>(
art_quick_throw_null_pointer_exception_from_signal);
- // Pass the faulting address as the first argument of
- // art_quick_throw_null_pointer_exception_from_signal.
-#if defined(__x86_64__)
- uc->CTX_RDI = reinterpret_cast<uintptr_t>(sig->si_addr);
-#else
- uc->CTX_EAX = reinterpret_cast<uintptr_t>(sig->si_addr);
-#endif
VLOG(signals) << "Generating null pointer exception";
return true;
}
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 646a80c..0beb2a4 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -224,10 +224,11 @@
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(kSaveEverything)
+ * when EDI is already saved.
*/
-MACRO2(SETUP_SAVE_EVERYTHING_FRAME, got_reg, temp_reg)
- // Save core registers.
- PUSH edi
+MACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED, got_reg, temp_reg)
+ // Save core registers from highest to lowest to agree with core spills bitmap.
+ // EDI, or at least a placeholder for it, is already on the stack.
PUSH esi
PUSH ebp
PUSH ebx
@@ -264,6 +265,15 @@
#endif
END_MACRO
+ /*
+ * Macro that sets up the callee save frame to conform with
+ * Runtime::CreateCalleeSaveMethod(kSaveEverything)
+ */
+MACRO2(SETUP_SAVE_EVERYTHING_FRAME, got_reg, temp_reg)
+ PUSH edi
+ SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED RAW_VAR(got_reg), RAW_VAR(temp_reg)
+END_MACRO
+
MACRO0(RESTORE_SAVE_EVERYTHING_FRAME)
// Restore FPRs. Method and padding is still on the stack.
movsd 16(%esp), %xmm0
@@ -320,7 +330,6 @@
MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
DEFINE_FUNCTION VAR(c_name)
SETUP_SAVE_ALL_CALLEE_SAVES_FRAME ebx, ebx // save all registers as basis for long jump context
- mov %esp, %ecx
// Outgoing argument set up
subl MACRO_LITERAL(8), %esp // alignment padding
CFI_ADJUST_CFA_OFFSET(8)
@@ -354,7 +363,23 @@
/*
* Call installed by a signal handler to create and deliver a NullPointerException.
*/
-ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception_from_signal, artThrowNullPointerExceptionFromSignal
+DEFINE_FUNCTION_CUSTOM_CFA art_quick_throw_null_pointer_exception_from_signal, 2 * __SIZEOF_POINTER__
+ // Fault address and return address were saved by the fault handler.
+ // Save all registers as basis for long jump context; EDI will replace fault address later.
+ SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED ebx, ebx
+ // Retrieve fault address and save EDI.
+ movl (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__)(%esp), %eax
+ movl %edi, (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__)(%esp)
+ CFI_REL_OFFSET(%edi, (FRAME_SIZE_SAVE_EVERYTHING - 2 * __SIZEOF_POINTER__))
+ // Outgoing argument set up
+ subl MACRO_LITERAL(8), %esp // alignment padding
+ CFI_ADJUST_CFA_OFFSET(8)
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ CFI_ADJUST_CFA_OFFSET(4)
+ PUSH eax // pass arg1
+ call SYMBOL(artThrowNullPointerExceptionFromSignal) // (addr, self)
+ UNREACHABLE
+END_FUNCTION art_quick_throw_null_pointer_exception
/*
* Called by managed code to create and deliver an ArithmeticException.