Index: src/x64/full-codegen-x64.cc |
=================================================================== |
--- src/x64/full-codegen-x64.cc (revision 5336) |
+++ src/x64/full-codegen-x64.cc (working copy) |
@@ -253,7 +253,7 @@ |
case Expression::kTest: |
// For simplicity we always test the accumulator register. |
if (!reg.is(result_register())) __ movq(result_register(), reg); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -282,7 +282,7 @@ |
case Expression::kTest: |
Move(result_register(), slot); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -308,7 +308,7 @@ |
case Expression::kTest: |
__ Move(result_register(), lit->handle()); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -335,7 +335,7 @@ |
case Expression::kTest: |
__ pop(result_register()); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -370,37 +370,12 @@ |
case Expression::kTest: |
__ Drop(count); |
if (!reg.is(result_register())) __ movq(result_register(), reg); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
-void FullCodeGenerator::PrepareTest(Label* materialize_true, |
- Label* materialize_false, |
- Label** if_true, |
- Label** if_false) { |
- switch (context_) { |
- case Expression::kUninitialized: |
- UNREACHABLE(); |
- break; |
- case Expression::kEffect: |
- // In an effect context, the true and the false case branch to the |
- // same label. |
- *if_true = *if_false = materialize_true; |
- break; |
- case Expression::kValue: |
- *if_true = materialize_true; |
- *if_false = materialize_false; |
- break; |
- case Expression::kTest: |
- *if_true = true_label_; |
- *if_false = false_label_; |
- break; |
- } |
-} |
- |
- |
void FullCodeGenerator::Apply(Expression::Context context, |
Label* materialize_true, |
Label* materialize_false) { |
@@ -463,7 +438,11 @@ |
break; |
} |
case Expression::kTest: |
- __ jmp(flag ? true_label_ : false_label_); |
+ if (flag) { |
+ if (true_label_ != fall_through_) __ jmp(true_label_); |
+ } else { |
+ if (false_label_ != fall_through_) __ jmp(false_label_); |
+ } |
break; |
} |
} |
@@ -1744,7 +1723,9 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_true); |
__ jmp(if_false); |
@@ -1761,10 +1742,12 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
Condition positive_smi = __ CheckPositiveSmi(rax); |
- Split(positive_smi, if_true, if_false, NULL); |
+ Split(positive_smi, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1778,7 +1761,9 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ CompareRoot(rax, Heap::kNullValueRootIndex); |
@@ -1792,7 +1777,7 @@ |
__ cmpq(rbx, Immediate(FIRST_JS_OBJECT_TYPE)); |
__ j(below, if_false); |
__ cmpq(rbx, Immediate(LAST_JS_OBJECT_TYPE)); |
- Split(below_equal, if_true, if_false, NULL); |
+ Split(below_equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1806,11 +1791,13 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx); |
- Split(above_equal, if_true, if_false, NULL); |
+ Split(above_equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1824,13 +1811,15 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
__ testb(FieldOperand(rbx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- Split(not_zero, if_true, if_false, NULL); |
+ Split(not_zero, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1845,7 +1834,9 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
// Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only |
// used in a few functions in runtime.js which should not normally be hit by |
@@ -1863,11 +1854,13 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1881,11 +1874,13 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ CmpObjectType(rax, JS_ARRAY_TYPE, rbx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1899,11 +1894,13 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ JumpIfSmi(rax, if_false); |
__ CmpObjectType(rax, JS_REGEXP_TYPE, rbx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1916,7 +1913,9 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
// Get the frame pointer for the calling frame. |
__ movq(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
@@ -1932,7 +1931,7 @@ |
__ bind(&check_frame_marker); |
__ SmiCompare(Operand(rax, StandardFrameConstants::kMarkerOffset), |
Smi::FromInt(StackFrame::CONSTRUCT)); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1948,11 +1947,13 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
__ pop(rbx); |
__ cmpq(rax, rbx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -2612,12 +2613,11 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- |
+ Label* fall_through = NULL; |
// Notice that the labels are swapped. |
- PrepareTest(&materialize_true, &materialize_false, &if_false, &if_true); |
- |
- VisitForControl(expr->expression(), if_true, if_false); |
- |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_false, &if_true, &fall_through); |
+ VisitForControl(expr->expression(), if_true, if_false, fall_through); |
Apply(context_, if_false, if_true); // Labels swapped. |
break; |
} |
@@ -2979,14 +2979,16 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
// First we try a fast inlined version of the compare when one of |
// the operands is a literal. |
Token::Value op = expr->op(); |
Expression* left = expr->left(); |
Expression* right = expr->right(); |
- if (TryLiteralCompare(op, left, right, if_true, if_false, NULL)) { |
+ if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) { |
Apply(context_, if_true, if_false); |
return; |
} |
@@ -2997,7 +2999,7 @@ |
VisitForValue(expr->right(), kStack); |
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
__ CompareRoot(rax, Heap::kTrueValueRootIndex); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
break; |
case Token::INSTANCEOF: { |
@@ -3006,7 +3008,7 @@ |
__ CallStub(&stub); |
__ testq(rax, rax); |
// The stub returns 0 for true. |
- Split(zero, if_true, if_false, NULL); |
+ Split(zero, if_true, if_false, fall_through); |
break; |
} |
@@ -3060,7 +3062,7 @@ |
CompareStub stub(cc, strict); |
__ CallStub(&stub); |
__ testq(rax, rax); |
- Split(cc, if_true, if_false, NULL); |
+ Split(cc, if_true, if_false, fall_through); |
} |
} |
@@ -3075,12 +3077,14 @@ |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
Label* if_false = NULL; |
- PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); |
+ Label* fall_through = NULL; |
+ PrepareTest(&materialize_true, &materialize_false, |
+ &if_true, &if_false, &fall_through); |
VisitForValue(expr->expression(), kAccumulator); |
__ CompareRoot(rax, Heap::kNullValueRootIndex); |
if (expr->is_strict()) { |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
} else { |
__ j(equal, if_true); |
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
@@ -3091,7 +3095,7 @@ |
__ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); |
__ testb(FieldOperand(rdx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- Split(not_zero, if_true, if_false, NULL); |
+ Split(not_zero, if_true, if_false, fall_through); |
} |
Apply(context_, if_true, if_false); |
} |