diff options
| author | 2016-11-07 18:50:32 +0000 | |
|---|---|---|
| committer | 2017-01-03 14:07:44 +0000 | |
| commit | 4ec76d28f0f808117272134347abf828eea80b91 (patch) | |
| tree | be3b7c5125549dd772a622603e69353466f2f356 /compiler | |
| parent | 66e3919bc42ddca40302ce5ee32e3ade248dd2b6 (diff) | |
Avoid scratch register exhaustion during ARM64 stack slot moves.
On ARM64, do not limit the selection of a scratch register
used in a move between two stack slots (or between two
double stack slots) to VIXL's floating-point register pool,
as it contains only one register (D31) and can be exhausted
in some rare cases. Instead, query both the core and the FP
register pools.
Add a regression run-test (626-checker-arm64-scratch-register).
Test: m test-art-target (on ARM64)
Bug: 32545705
Change-Id: I6203a4340e3c8b4f4879c07ed1be4c433c311c0f
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 13616db535..5c33fe1a7d 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1533,8 +1533,17 @@ void CodeGeneratorARM64::MoveLocation(Location destination, DCHECK(source.IsStackSlot() || source.IsDoubleStackSlot()); DCHECK(source.IsDoubleStackSlot() == destination.IsDoubleStackSlot()); UseScratchRegisterScope temps(GetVIXLAssembler()); - // There is generally less pressure on FP registers. - FPRegister temp = destination.IsDoubleStackSlot() ? temps.AcquireD() : temps.AcquireS(); + // Use any scratch register (a core or a floating-point one) + // from VIXL scratch register pools as a temporary. + // + // We used to only use the FP scratch register pool, but in some + // rare cases the only register from this pool (D31) would + // already be used (e.g. within a ParallelMove instruction, when + // a move is blocked by a another move requiring a scratch FP + // register, which would reserve D31). To prevent this issue, we + // ask for a scratch register of any type (core or FP). + CPURegister temp = + temps.AcquireCPURegisterOfSize(destination.IsDoubleStackSlot() ? kXRegSize : kWRegSize); __ Ldr(temp, StackOperandFrom(source)); __ Str(temp, StackOperandFrom(destination)); } |