Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 5322) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -2038,41 +2038,6 @@ |
ConstantSmiComparison(cc, strict, dest, &left_side, &right_side, |
left_side_constant_smi, right_side_constant_smi, |
is_loop_condition); |
- } else if (cc == equal && |
- (left_side_constant_null || right_side_constant_null)) { |
- // To make null checks efficient, we check if either the left side or |
- // the right side is the constant 'null'. |
- // If so, we optimize the code by inlining a null check instead of |
- // calling the (very) general runtime routine for checking equality. |
- Result operand = left_side_constant_null ? right_side : left_side; |
- right_side.Unuse(); |
- left_side.Unuse(); |
- operand.ToRegister(); |
- __ CompareRoot(operand.reg(), Heap::kNullValueRootIndex); |
- if (strict) { |
- operand.Unuse(); |
- dest->Split(equal); |
- } else { |
- // The 'null' value is only equal to 'undefined' if using non-strict |
- // comparisons. |
- dest->true_target()->Branch(equal); |
- __ CompareRoot(operand.reg(), Heap::kUndefinedValueRootIndex); |
- dest->true_target()->Branch(equal); |
- Condition is_smi = masm_->CheckSmi(operand.reg()); |
- dest->false_target()->Branch(is_smi); |
- |
- // It can be an undetectable object. |
- // Use a scratch register in preference to spilling operand.reg(). |
- Result temp = allocator()->Allocate(); |
- ASSERT(temp.is_valid()); |
- __ movq(temp.reg(), |
- FieldOperand(operand.reg(), HeapObject::kMapOffset)); |
- __ testb(FieldOperand(temp.reg(), Map::kBitFieldOffset), |
- Immediate(1 << Map::kIsUndetectable)); |
- temp.Unuse(); |
- operand.Unuse(); |
- dest->Split(not_zero); |
- } |
} else if (left_side_constant_1_char_string || |
right_side_constant_1_char_string) { |
if (left_side_constant_1_char_string && right_side_constant_1_char_string) { |
@@ -5096,8 +5061,8 @@ |
(node->value()->AsBinaryOperation() != NULL && |
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
// Construct the implicit binary operation. |
- BinaryOperation expr(node, node->binary_op(), node->target(), |
- node->value()); |
+ BinaryOperation expr(node->binary_op(), node->target(), node->value()); |
+ expr.CopyAnalysisResultsFrom(node); |
GenericBinaryOperation(&expr, |
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
} else { |
@@ -5188,8 +5153,8 @@ |
(node->value()->AsBinaryOperation() != NULL && |
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
// Construct the implicit binary operation. |
- BinaryOperation expr(node, node->binary_op(), node->target(), |
- node->value()); |
+ BinaryOperation expr(node->binary_op(), node->target(), node->value()); |
+ expr.CopyAnalysisResultsFrom(node); |
GenericBinaryOperation(&expr, |
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
} else { |
@@ -5290,8 +5255,8 @@ |
bool overwrite_value = |
(node->value()->AsBinaryOperation() != NULL && |
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
- BinaryOperation expr(node, node->binary_op(), node->target(), |
- node->value()); |
+ BinaryOperation expr(node->binary_op(), node->target(), node->value()); |
+ expr.CopyAnalysisResultsFrom(node); |
GenericBinaryOperation(&expr, |
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
} else { |
@@ -8055,6 +8020,40 @@ |
} |
+void CodeGenerator::VisitCompareToNull(CompareToNull* node) { |
+ Comment cmnt(masm_, "[ CompareToNull"); |
+ |
+ Load(node->expression()); |
+ Result operand = frame_->Pop(); |
+ operand.ToRegister(); |
+ __ CompareRoot(operand.reg(), Heap::kNullValueRootIndex); |
+ if (node->is_strict()) { |
+ operand.Unuse(); |
+ destination()->Split(equal); |
+ } else { |
+ // The 'null' value is only equal to 'undefined' if using non-strict |
+ // comparisons. |
+ destination()->true_target()->Branch(equal); |
+ __ CompareRoot(operand.reg(), Heap::kUndefinedValueRootIndex); |
+ destination()->true_target()->Branch(equal); |
+ Condition is_smi = masm_->CheckSmi(operand.reg()); |
+ destination()->false_target()->Branch(is_smi); |
+ |
+ // It can be an undetectable object. |
+ // Use a scratch register in preference to spilling operand.reg(). |
+ Result temp = allocator()->Allocate(); |
+ ASSERT(temp.is_valid()); |
+ __ movq(temp.reg(), |
+ FieldOperand(operand.reg(), HeapObject::kMapOffset)); |
+ __ testb(FieldOperand(temp.reg(), Map::kBitFieldOffset), |
+ Immediate(1 << Map::kIsUndetectable)); |
+ temp.Unuse(); |
+ operand.Unuse(); |
+ destination()->Split(not_zero); |
+ } |
+} |
+ |
+ |
#ifdef DEBUG |
bool CodeGenerator::HasValidEntryRegisters() { |
return (allocator()->count(rax) == (frame()->is_used(rax) ? 1 : 0)) |