Reviewers: Kevin Millikin,

Description:
Change order of fast case checks before ToBooleanStub if input is likely a smi.

Until now we always perform the following fast case checks before
entering the generic ToBoolean stub:

1. check for false
2. check for true
3. check for undefined
4. check for smi == 0
5. check for smi != 0

With this change, if the type hints indicate that the input expression
is likely a smi, we re-arrange the order of the checks to:

1. check for smi == 0
2. check for smi != 0
3. check for false
4. check for true
5. check for undefined


Please review this at http://codereview.chromium.org/525032

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/ia32/codegen-ia32.h
  M     src/ia32/codegen-ia32.cc


Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc    (revision 3540)
+++ src/ia32/codegen-ia32.cc    (working copy)
@@ -446,7 +446,7 @@

   if (force_control && !dest->is_used()) {
     // Convert the TOS value into flow to the control destination.
-    ToBoolean(dest);
+    ToBoolean(dest, x->type()->IsLikelySmi());
   }

   ASSERT(!(force_control && !dest->is_used()));
@@ -705,7 +705,7 @@
 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and
 // convert it to a boolean in the condition code register or jump to
 // 'false_target'/'true_target' as appropriate.
-void CodeGenerator::ToBoolean(ControlDestination* dest) {
+void CodeGenerator::ToBoolean(ControlDestination* dest, bool likely_smi) {
   Comment cmnt(masm_, "[ ToBoolean");

   // The value to convert should be popped from the frame.
@@ -713,6 +713,16 @@
   value.ToRegister();
   // Fast case checks.

+  // For likely smi inputs perform smi checks first.
+  if (likely_smi) {
+    // Smi => false iff zero.
+    ASSERT(kSmiTag == 0);
+    __ test(value.reg(), Operand(value.reg()));
+    dest->false_target()->Branch(zero);
+    __ test(value.reg(), Immediate(kSmiTagMask));
+    dest->true_target()->Branch(zero);
+  }
+
   // 'false' => false.
   __ cmp(value.reg(), Factory::false_value());
   dest->false_target()->Branch(equal);
@@ -725,12 +735,14 @@
   __ cmp(value.reg(), Factory::undefined_value());
   dest->false_target()->Branch(equal);

-  // Smi => false iff zero.
-  ASSERT(kSmiTag == 0);
-  __ test(value.reg(), Operand(value.reg()));
-  dest->false_target()->Branch(zero);
-  __ test(value.reg(), Immediate(kSmiTagMask));
-  dest->true_target()->Branch(zero);
+  if (!likely_smi) {
+    // Smi => false iff zero.
+    ASSERT(kSmiTag == 0);
+    __ test(value.reg(), Operand(value.reg()));
+    dest->false_target()->Branch(zero);
+    __ test(value.reg(), Immediate(kSmiTagMask));
+    dest->true_target()->Branch(zero);
+  }

   // Call the stub for all other cases.
   frame_->Push(&value);  // Undo the Pop() from above.
@@ -5718,7 +5730,7 @@
       // ToBoolean.
       frame_->Dup();
       ControlDestination dest(&pop_and_continue, &exit, true);
-      ToBoolean(&dest);
+      ToBoolean(&dest, node->left()->type()->IsLikelySmi());

       // Pop the result of evaluating the first part.
       frame_->Drop();
@@ -5780,7 +5792,7 @@
       // ToBoolean.
       frame_->Dup();
       ControlDestination dest(&exit, &pop_and_continue, false);
-      ToBoolean(&dest);
+      ToBoolean(&dest, node->left()->type()->IsLikelySmi());

       // Pop the result of evaluating the first part.
       frame_->Drop();
Index: src/ia32/codegen-ia32.h
===================================================================
--- src/ia32/codegen-ia32.h     (revision 3540)
+++ src/ia32/codegen-ia32.h     (working copy)
@@ -430,7 +430,7 @@

   // Translate the value on top of the frame into control flow to the
   // control destination.
-  void ToBoolean(ControlDestination* destination);
+  void ToBoolean(ControlDestination* destination, bool likely_smi);

   void GenericBinaryOperation(
       Token::Value op,


-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to