OSDN Git Service

Fix LoadValue{Wide} to free temp when reg classes are not matched
authorSerguei Katkov <serguei.i.katkov@intel.com>
Wed, 29 Oct 2014 07:48:02 +0000 (13:48 +0600)
committerSerguei Katkov <serguei.i.katkov@intel.com>
Wed, 5 Nov 2014 06:23:56 +0000 (12:23 +0600)
If the current register mapping does not match the required one we
are allocating a new temp and make a copy. After that we are clobbering
the old mapping of VR to physical register. However we can also free it
for future allocations as soon as it will not used more.

This is a fix of the bug I met. The reason of the dex2oat crash was that
GenInlinedMinMaxFP loaded two sources to fp registers. It appeared that
both of them were live in two pairs of core regs. As a result after
loading of them all 4 temps available for x86 platfrom are marked as in use.
As a result after an attempt to allocate new temp to load a constant
required by GenInlinedMinMaxFP register allocator reported that there is
no available temp registers.

Change-Id: I9233012e39de1e574761f3d9bd3cad80d743e522
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
compiler/dex/quick/gen_loadstore.cc

index 39b40a0..d314601 100644 (file)
@@ -149,8 +149,9 @@ RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
       // Wrong register class, realloc, copy and transfer ownership.
       RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
       OpRegCopy(new_reg, rl_src.reg);
-      // Clobber the old reg.
+      // Clobber the old regs and free it.
       Clobber(rl_src.reg);
+      FreeTemp(rl_src.reg);
       // ...and mark the new one live.
       rl_src.reg = new_reg;
       MarkLive(rl_src);
@@ -232,8 +233,9 @@ RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
       // Wrong register class, realloc, copy and transfer ownership.
       RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
       OpRegCopyWide(new_regs, rl_src.reg);
-      // Clobber the old regs.
+      // Clobber the old regs and free it.
       Clobber(rl_src.reg);
+      FreeTemp(rl_src.reg);
       // ...and mark the new ones live.
       rl_src.reg = new_regs;
       MarkLive(rl_src);