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