From 952dbb19cd094b8bfb01dbb33e0878db429e499a Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Thu, 28 Jul 2016 12:01:51 +0100 Subject: Change suspend entrypoint to save all registers. We avoid the need to save/restore registers in slow paths and get significant code size savings. On Nexus 9, AOSP: - 32-bit boot.oat: -1.4MiB (-1.9%) - 64-bit boot.oat: -2.0MiB (-2.3%) - other 32-bit oat files in dalvik-cache: -200KiB (-1.7%) - other 64-bit oat files in dalvik-cache: -2.3MiB (-2.1%) Test: Run ART test suite on host and Nexus 9 with gc stress. Bug: 30212852 Change-Id: I7015afc1e7d30341618c9200a3dc9ae277afd134 --- compiler/optimizing/code_generator.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'compiler/optimizing/code_generator.cc') diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 3269dc6605..94ecb1c63c 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -765,16 +765,24 @@ void CodeGenerator::RecordPcInfo(HInstruction* instruction, LocationSummary* locations = instruction->GetLocations(); uint32_t register_mask = locations->GetRegisterMask(); - if (locations->OnlyCallsOnSlowPath()) { - // In case of slow path, we currently set the location of caller-save registers - // to register (instead of their stack location when pushed before the slow-path - // call). Therefore register_mask contains both callee-save and caller-save - // registers that hold objects. We must remove the caller-save from the mask, since - // they will be overwritten by the callee. - register_mask &= core_callee_save_mask_; + if (instruction->IsSuspendCheck()) { + // Suspend check has special ABI that saves the caller-save registers in callee, + // so we want to emit stack maps containing the registers. + // TODO: Register allocator still reserves space for the caller-save registers. + // We should add slow-path-specific caller-save information into LocationSummary + // and refactor the code here as well as in the register allocator to use it. + } else { + if (locations->OnlyCallsOnSlowPath()) { + // In case of slow path, we currently set the location of caller-save registers + // to register (instead of their stack location when pushed before the slow-path + // call). Therefore register_mask contains both callee-save and caller-save + // registers that hold objects. We must remove the caller-save from the mask, since + // they will be overwritten by the callee. + register_mask &= core_callee_save_mask_; + } + // The register mask must be a subset of callee-save registers. + DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask); } - // The register mask must be a subset of callee-save registers. - DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask); stack_map_stream_.BeginStackMapEntry(outer_dex_pc, native_pc, register_mask, -- cgit v1.2.3-59-g8ed1b