Smi immediates are not supported on x64. Do not use it.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Apr 2014 15:32:06 +0000 (15:32 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Apr 2014 15:32:06 +0000 (15:32 +0000)
R=jkummerow@chromium.org
BUG=358059
LOG=N

Review URL: https://codereview.chromium.org/217083003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20409 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc
test/mjsunit/regress/regress-358059.js [new file with mode: 0644]

index 0c907e4..a64d3e2 100644 (file)
@@ -1820,6 +1820,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
 
   if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
     if (right->IsConstantOperand()) {
+      ASSERT(!target_rep.IsSmi());  // No support for smi-immediates.
       int32_t offset = ToInteger32(LConstantOperand::cast(right));
       if (is_p) {
         __ leap(ToRegister(instr->result()),
@@ -1838,6 +1839,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
     }
   } else {
     if (right->IsConstantOperand()) {
+      ASSERT(!target_rep.IsSmi());  // No support for smi-immediates.
       if (is_p) {
         __ addp(ToRegister(left),
                 Immediate(ToInteger32(LConstantOperand::cast(right))));
index b174a0e..d1c7731 100644 (file)
@@ -1532,14 +1532,19 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     HValue* right_candidate = instr->BetterRightOperand();
-    LOperand* right = use_lea
-        ? UseRegisterOrConstantAtStart(right_candidate)
-        : UseOrConstantAtStart(right_candidate);
+    LOperand* right;
+    if (instr->representation().IsSmi()) {
+      // We cannot add a tagged immediate to a tagged value,
+      // so we request it in a register.
+      right = UseRegisterAtStart(right_candidate);
+    } else {
+      right = use_lea ? UseRegisterOrConstantAtStart(right_candidate)
+                      : UseOrConstantAtStart(right_candidate);
+    }
     LAddI* add = new(zone()) LAddI(left, right);
     bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
-    LInstruction* result = use_lea
-        ? DefineAsRegister(add)
-        : DefineSameAsFirst(add);
+    LInstruction* result = use_lea ? DefineAsRegister(add)
+                                   : DefineSameAsFirst(add);
     if (can_overflow) {
       result = AssignEnvironment(result);
     }
diff --git a/test/mjsunit/regress/regress-358059.js b/test/mjsunit/regress/regress-358059.js
new file mode 100644 (file)
index 0000000..30738f9
--- /dev/null
@@ -0,0 +1,13 @@
+// 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
+
+function f(a, b) { return b + (a.x++); }
+var o = {};
+o.__defineGetter__('x', function() { return 1; });
+assertEquals(4, f(o, 3));
+assertEquals(4, f(o, 3));
+%OptimizeFunctionOnNextCall(f);
+assertEquals(4, f(o, 3));