MIPS: Refine CountOperation of FullCodeGen.
authorplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 19:28:58 +0000 (19:28 +0000)
committerplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 19:28:58 +0000 (19:28 +0000)
Port r17547 (a4b59e4)

BUG=
R=plind44@gmail.com

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

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

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

src/mips/full-codegen-mips.cc

index 6947ca8..caa7352 100644 (file)
@@ -4442,15 +4442,48 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
     PrepareForBailoutForId(prop->LoadId(), TOS_REG);
   }
 
-  // Call ToNumber only if operand is not a smi.
-  Label no_conversion;
+  // Inline smi case if we are in a loop.
+  Label stub_call, done;
+  JumpPatchSite patch_site(masm_);
+
+  int count_value = expr->op() == Token::INC ? 1 : -1;
+  __ mov(a0, v0);
   if (ShouldInlineSmiCase(expr->op())) {
-    __ JumpIfSmi(v0, &no_conversion);
+    Label slow;
+    patch_site.EmitJumpIfNotSmi(v0, &slow);
+
+    // Save result for postfix expressions.
+    if (expr->is_postfix()) {
+      if (!context()->IsEffect()) {
+        // Save the result on the stack. If we have a named or keyed property
+        // we store the result under the receiver that is currently on top
+        // of the stack.
+        switch (assign_type) {
+          case VARIABLE:
+            __ push(v0);
+            break;
+          case NAMED_PROPERTY:
+            __ sw(v0, MemOperand(sp, kPointerSize));
+            break;
+          case KEYED_PROPERTY:
+            __ sw(v0, MemOperand(sp, 2 * kPointerSize));
+            break;
+        }
+      }
+    }
+
+    Register scratch1 = a1;
+    Register scratch2 = t0;
+    __ li(scratch1, Operand(Smi::FromInt(count_value)));
+    __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2);
+    __ BranchOnNoOverflow(&done, scratch2);
+    // Call stub. Undo operation first.
+    __ Move(v0, a0);
+    __ jmp(&stub_call);
+    __ bind(&slow);
   }
-  __ mov(a0, v0);
   ToNumberStub convert_stub;
   __ CallStub(&convert_stub);
-  __ bind(&no_conversion);
 
   // Save result for postfix expressions.
   if (expr->is_postfix()) {
@@ -4471,24 +4504,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
       }
     }
   }
-  __ mov(a0, result_register());
-
-  // Inline smi case if we are in a loop.
-  Label stub_call, done;
-  JumpPatchSite patch_site(masm_);
 
-  int count_value = expr->op() == Token::INC ? 1 : -1;
-  if (ShouldInlineSmiCase(expr->op())) {
-    __ li(a1, Operand(Smi::FromInt(count_value)));
-    __ AdduAndCheckForOverflow(v0, a0, a1, t0);
-    __ BranchOnOverflow(&stub_call, t0);  // Do stub on overflow.
-
-    // We could eliminate this smi check if we split the code at
-    // the first smi check before calling ToNumber.
-    patch_site.EmitJumpIfSmi(v0, &done);
-    __ bind(&stub_call);
-  }
-  __ mov(a1, a0);
+  __ bind(&stub_call);
+  __ mov(a1, v0);
   __ li(a0, Operand(Smi::FromInt(count_value)));
 
   // Record position before stub call.