OSDN Git Service

Quick compiler: fix DCHECK
authorbuzbee <buzbee@google.com>
Mon, 25 Aug 2014 16:34:03 +0000 (09:34 -0700)
committerbuzbee <buzbee@google.com>
Mon, 25 Aug 2014 22:49:16 +0000 (15:49 -0700)
A DCHECK intended to verify the soundness of the mapping between
a wide Dalvik value and a pair of temp registers incorrectly fired
when the temp register pair was associated with a wide temporary
(i.e. - when (SReg() == INVALID_SREG)).

In this particular situation, the wideness flag is meaningful only when
there is an associated valid vreg.  Code rearranged to only perform
the DCHECK and reset the partner's wideness bit when we're dealing with
a live wide value.

b/16484538

Change-Id: I3b8a7bebc5d918c65ea56ae8db0a8a5cd8003386

compiler/dex/quick/ralloc_util.cc

index be966e1..4021c95 100644 (file)
@@ -359,19 +359,19 @@ RegStorage Mir2Lir::AllocTempBody(GrowableArray<RegisterInfo*> &regs, int* next_
     RegisterInfo* info = regs.Get(next);
     // Try to allocate a register that doesn't hold a live value.
     if (info->IsTemp() && !info->InUse() && info->IsDead()) {
-      Clobber(info->GetReg());
-      info->MarkInUse();
-      /*
-       * NOTE: "wideness" is an attribute of how the container is used, not its physical size.
-       * The caller will set wideness as appropriate.
-       */
+      // If it's wide, split it up.
       if (info->IsWide()) {
-        RegisterInfo* partner = GetRegInfo(info->Partner());
-        DCHECK_EQ(info->GetReg().GetRegNum(), partner->Partner().GetRegNum());
-        DCHECK(partner->IsWide());
+        // If the pair was associated with a wide value, unmark the partner as well.
+        if (info->SReg() != INVALID_SREG) {
+          RegisterInfo* partner = GetRegInfo(info->Partner());
+          DCHECK_EQ(info->GetReg().GetRegNum(), partner->Partner().GetRegNum());
+          DCHECK(partner->IsWide());
+          partner->SetIsWide(false);
+        }
         info->SetIsWide(false);
-        partner->SetIsWide(false);
       }
+      Clobber(info->GetReg());
+      info->MarkInUse();
       *next_temp = next + 1;
       return info->GetReg();
     }