Use implicit null checks inside try blocks.
Make implicit null check entrypoint save all registers, use
platform-specific approach to still pass the fault address.
Allow implicit null checks in try blocks.
On Nexus 9, AOSP ToT, the boot.oat size reduction is
prebuilt multi-part boot image:
- 32-bit boot.oat: -452KiB (-0.7%)
- 64-bit boot.oat: -482KiB (-0.7%)
on-device built single boot image:
- 32-bit boot.oat: -444KiB (-0.7%)
- 64-bit boot.oat: -488KiB (-0.7%)
Test: Run ART test suite on host and Nexus 9.
Test: Build aosp_mips64-eng.
Change-Id: I279f3ab57e2e2f338131c5cac45c51b673bdca19
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index a3f053b..3fc83ba 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -173,6 +173,29 @@
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(kSaveEverything)
+ * when core registers are already saved.
+ */
+.macro SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED rTemp
+ @ 14 words of callee saves and args already saved.
+ vpush {d0-d15} @ 32 words, 2 for each of the 16 saved doubles.
+ .cfi_adjust_cfa_offset 128
+ sub sp, #8 @ 2 words of space, alignment padding and Method*
+ .cfi_adjust_cfa_offset 8
+ RUNTIME_CURRENT1 \rTemp @ Load Runtime::Current into rTemp.
+ @ Load kSaveEverything Method* into rTemp.
+ ldr \rTemp, [\rTemp, #RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET]
+ str \rTemp, [sp, #0] @ Place Method* at bottom of stack.
+ str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame.
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_SAVE_EVERYTHING != 56 + 128 + 8)
+#error "FRAME_SIZE_SAVE_EVERYTHING(ARM) size not as expected."
+#endif
+.endm
+
+ /*
+ * Macro that sets up the callee save frame to conform with
+ * Runtime::CreateCalleeSaveMethod(kSaveEverything)
*/
.macro SETUP_SAVE_EVERYTHING_FRAME rTemp
push {r0-r12, lr} @ 14 words of callee saves and args.
@@ -191,20 +214,7 @@
.cfi_rel_offset r11, 44
.cfi_rel_offset ip, 48
.cfi_rel_offset lr, 52
- vpush {d0-d15} @ 32 words, 2 for each of the 16 saved doubles.
- .cfi_adjust_cfa_offset 128
- sub sp, #8 @ 2 words of space, alignment padding and Method*
- .cfi_adjust_cfa_offset 8
- RUNTIME_CURRENT1 \rTemp @ Load Runtime::Current into rTemp.
- @ Load kSaveEverything Method* into rTemp.
- ldr \rTemp, [\rTemp, #RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET]
- str \rTemp, [sp, #0] @ Place Method* at bottom of stack.
- str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame.
-
- // Ugly compile-time check, but we only have the preprocessor.
-#if (FRAME_SIZE_SAVE_EVERYTHING != 56 + 128 + 8)
-#error "FRAME_SIZE_SAVE_EVERYTHING(ARM) size not as expected."
-#endif
+ SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED \rTemp
.endm
.macro RESTORE_SAVE_EVERYTHING_FRAME
@@ -356,7 +366,34 @@
/*
* 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
+ .extern art_quick_throw_null_pointer_exception_from_signal
+ENTRY art_quick_throw_null_pointer_exception_from_signal
+ // The fault handler pushes the gc map address, i.e. "return address", to stack
+ // and passes the fault address in LR. So we need to set up the CFI info accordingly.
+ .cfi_def_cfa_offset __SIZEOF_POINTER__
+ .cfi_rel_offset lr, 0
+ push {r0-r12} @ 13 words of callee saves and args; LR already saved.
+ .cfi_adjust_cfa_offset 52
+ .cfi_rel_offset r0, 0
+ .cfi_rel_offset r1, 4
+ .cfi_rel_offset r2, 8
+ .cfi_rel_offset r3, 12
+ .cfi_rel_offset r4, 16
+ .cfi_rel_offset r5, 20
+ .cfi_rel_offset r6, 24
+ .cfi_rel_offset r7, 28
+ .cfi_rel_offset r8, 32
+ .cfi_rel_offset r9, 36
+ .cfi_rel_offset r10, 40
+ .cfi_rel_offset r11, 44
+ .cfi_rel_offset ip, 48
+
+ @ save all registers as basis for long jump context
+ SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED r1
+ mov r0, lr @ pass the fault address stored in LR by the fault handler.
+ mov r1, r9 @ pass Thread::Current
+ b artThrowNullPointerExceptionFromSignal @ (Thread*)
+END art_quick_throw_null_pointer_exception_from_signal
/*
* Called by managed code to create and deliver an ArithmeticException.