From 997ce05289846eca1070e918a0fa2735c727b2e7 Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Thu, 6 Mar 2014 16:22:47 +0000 Subject: [PATCH] Fix for failing asserts in HBoundsCheck code generation on x64: use proper cmp operation width instead of asserting that Integer32 values should be zero extended. Similar to chromium:345820. BUG=349465 LOG=N R=verwaest@chromium.org Review URL: https://codereview.chromium.org/188703002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19694 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/lithium-codegen-x64.cc | 35 +++++++++++++++++----------- test/mjsunit/regress/regress-crbug-349465.js | 17 ++++++++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-349465.js diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 383cf37..695fae9 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -4025,44 +4025,51 @@ void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) { void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { - if (instr->hydrogen()->skip_check()) return; + HBoundsCheck* hinstr = instr->hydrogen(); + if (hinstr->skip_check()) return; + + Representation representation = hinstr->length()->representation(); + ASSERT(representation.Equals(hinstr->index()->representation())); + ASSERT(representation.IsSmiOrInteger32()); if (instr->length()->IsRegister()) { Register reg = ToRegister(instr->length()); - if (!instr->hydrogen()->length()->representation().IsSmi()) { - __ AssertZeroExtended(reg); - } + if (instr->index()->IsConstantOperand()) { int32_t constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsSmi()) { + if (representation.IsSmi()) { __ Cmp(reg, Smi::FromInt(constant_index)); } else { - __ cmpq(reg, Immediate(constant_index)); + __ cmpl(reg, Immediate(constant_index)); } } else { Register reg2 = ToRegister(instr->index()); - if (!instr->hydrogen()->index()->representation().IsSmi()) { - __ AssertZeroExtended(reg2); + if (representation.IsSmi()) { + __ cmpq(reg, reg2); + } else { + __ cmpl(reg, reg2); } - __ cmpq(reg, reg2); } } else { Operand length = ToOperand(instr->length()); if (instr->index()->IsConstantOperand()) { int32_t constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsSmi()) { + if (representation.IsSmi()) { __ Cmp(length, Smi::FromInt(constant_index)); } else { - __ cmpq(length, Immediate(constant_index)); + __ cmpl(length, Immediate(constant_index)); } } else { - __ cmpq(length, ToRegister(instr->index())); + if (representation.IsSmi()) { + __ cmpq(length, ToRegister(instr->index())); + } else { + __ cmpl(length, ToRegister(instr->index())); + } } } - Condition condition = - instr->hydrogen()->allow_equality() ? below : below_equal; + Condition condition = hinstr->allow_equality() ? below : below_equal; ApplyCheckIf(condition, instr); } diff --git a/test/mjsunit/regress/regress-crbug-349465.js b/test/mjsunit/regress/regress-crbug-349465.js new file mode 100644 index 0000000..335ea1e --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-349465.js @@ -0,0 +1,17 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --debug-code --use-gvn + +function f(a, base) { + a[base] = 1; + a[base + 4] = 2; + a[base] = 3; +} +var a1 = new Array(1024); +var a2 = new Array(128); +f(a1, 1); +f(a2, -2); +%OptimizeFunctionOnNextCall(f); +f(a1, -2); -- 2.7.4