From ee5b15dbf2264ca6a9720f6d6ac80d0257fc18a9 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Wed, 3 Apr 2013 17:26:59 +0000 Subject: [PATCH] MIPS: Ensure UseRegisterAtStart not used with fixed temp/return register Port r14124 (f116e8b9) BUG= Review URL: https://codereview.chromium.org/13557002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-mips.cc | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 5d1364e..652c7ca 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -871,6 +871,35 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = current->CompileToLithium(this); if (instr != NULL) { +#if DEBUG + // Make sure that the lithium instruction has either no fixed register + // constraints in temps or the result OR no uses that are only used at + // start. If this invariant doesn't hold, the register allocator can decide + // to insert a split of a range immediately before the instruction due to an + // already allocated register needing to be used for the instruction's fixed + // register constraint. In this case, The register allocator won't see an + // interference between the split child and the use-at-start (it would if + // the it was just a plain use), so it is free to move the split child into + // the same register that is used for the use-at-start. + // See https://code.google.com/p/chromium/issues/detail?id=201590 + if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { + int fixed = 0; + int used_at_start = 0; + for (UseIterator it(instr); !it.Done(); it.Advance()) { + LUnallocated* operand = LUnallocated::cast(it.Current()); + if (operand->IsUsedAtStart()) ++used_at_start; + } + if (instr->Output() != NULL) { + if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; + } + for (TempIterator it(instr); !it.Done(); it.Advance()) { + LUnallocated* operand = LUnallocated::cast(it.Current()); + if (operand->HasFixedPolicy()) ++fixed; + } + ASSERT(fixed == 0 || used_at_start == 0); + } +#endif + if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } @@ -1116,7 +1145,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); return DefineFixedDouble(result, f4); } else { - LOperand* input = UseRegisterAtStart(instr->value()); + LOperand* input = UseRegister(instr->value()); LOperand* temp = (op == kMathRound) ? FixedTemp(f6) : (op == kMathFloor) ? TempRegister() : NULL; @@ -1691,11 +1720,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignEnvironment(DefineAsRegister(res)); } else { ASSERT(to.IsInteger32()); - LOperand* value = UseRegisterAtStart(instr->value()); + LOperand* value = NULL; LInstruction* res = NULL; if (instr->value()->type().IsSmi()) { + value = UseRegisterAtStart(instr->value()); res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); } else { + value = UseRegister(instr->value()); LOperand* temp1 = TempRegister(); LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() : NULL; -- 2.7.4