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/fault_handler_arm.cc b/runtime/arch/arm/fault_handler_arm.cc
index befdd48..daa2dff 100644
--- a/runtime/arch/arm/fault_handler_arm.cc
+++ b/runtime/arch/arm/fault_handler_arm.cc
@@ -122,13 +122,16 @@
struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
uint8_t* ptr = reinterpret_cast<uint8_t*>(sc->arm_pc);
-
uint32_t instr_size = GetInstructionSize(ptr);
- sc->arm_lr = (sc->arm_pc + instr_size) | 1; // LR needs to point to gc map location
+ uintptr_t gc_map_location = (sc->arm_pc + instr_size) | 1;
+
+ // Push the gc map location to the stack and pass the fault address in LR.
+ sc->arm_sp -= sizeof(uintptr_t);
+ *reinterpret_cast<uintptr_t*>(sc->arm_sp) = gc_map_location;
+ sc->arm_lr = reinterpret_cast<uintptr_t>(info->si_addr);
sc->arm_pc = 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.
- sc->arm_r0 = reinterpret_cast<uintptr_t>(info->si_addr);
VLOG(signals) << "Generating null pointer exception";
return true;
}