Index: src/ia32/full-codegen-ia32.cc |
=================================================================== |
--- src/ia32/full-codegen-ia32.cc (revision 5336) |
+++ src/ia32/full-codegen-ia32.cc (working copy) |
@@ -246,7 +246,7 @@ |
case Expression::kTest: |
// For simplicity we always test the accumulator register. |
if (!reg.is(result_register())) __ mov(result_register(), reg); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -276,7 +276,7 @@ |
case Expression::kTest: |
// For simplicity we always test the accumulator register. |
Move(result_register(), slot); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -304,7 +304,7 @@ |
case Expression::kTest: |
// For simplicity we always test the accumulator register. |
__ mov(result_register(), lit->handle()); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -332,7 +332,7 @@ |
case Expression::kTest: |
// For simplicity we always test the accumulator register. |
__ pop(result_register()); |
- DoTest(true_label_, false_label_, NULL); |
+ DoTest(true_label_, false_label_, fall_through_); |
break; |
} |
} |
@@ -368,37 +368,12 @@ |
// For simplicity we always test the accumulator register. |
__ Drop(count); |
if (!reg.is(result_register())) __ mov(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) { |
@@ -461,7 +436,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; |
} |
} |
@@ -1735,10 +1714,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); |
__ test(eax, Immediate(kSmiTagMask)); |
- Split(zero, if_true, if_false, NULL); |
+ Split(zero, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1752,10 +1733,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); |
__ test(eax, Immediate(kSmiTagMask | 0x80000000)); |
- Split(zero, if_true, if_false, NULL); |
+ Split(zero, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1769,7 +1752,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(zero, if_false); |
@@ -1784,7 +1769,7 @@ |
__ cmp(ecx, FIRST_JS_OBJECT_TYPE); |
__ j(below, if_false); |
__ cmp(ecx, 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); |
} |
@@ -1798,12 +1783,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(equal, if_false); |
__ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx); |
- Split(above_equal, if_true, if_false, NULL); |
+ Split(above_equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1817,14 +1804,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(zero, if_false); |
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
__ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); |
__ test(ebx, 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); |
} |
@@ -1839,7 +1828,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 |
@@ -1857,12 +1848,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(zero, if_false); |
__ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1876,12 +1869,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(equal, if_false); |
__ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1895,12 +1890,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); |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(equal, if_false); |
__ CmpObjectType(eax, JS_REGEXP_TYPE, ebx); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -1913,7 +1910,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. |
__ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
@@ -1929,7 +1928,7 @@ |
__ bind(&check_frame_marker); |
__ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset), |
Immediate(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); |
} |
@@ -1945,11 +1944,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(ebx); |
__ cmp(eax, Operand(ebx)); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
Apply(context_, if_true, if_false); |
} |
@@ -2613,15 +2614,15 @@ |
case Token::NOT: { |
Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
+ |
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; |
} |
@@ -2988,14 +2989,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; |
} |
@@ -3006,7 +3009,7 @@ |
VisitForValue(expr->right(), kStack); |
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
__ cmp(eax, Factory::true_value()); |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
break; |
case Token::INSTANCEOF: { |
@@ -3015,7 +3018,7 @@ |
__ CallStub(&stub); |
__ test(eax, Operand(eax)); |
// The stub returns 0 for true. |
- Split(zero, if_true, if_false, NULL); |
+ Split(zero, if_true, if_false, fall_through); |
break; |
} |
@@ -3072,7 +3075,7 @@ |
CompareStub stub(cc, strict); |
__ CallStub(&stub); |
__ test(eax, Operand(eax)); |
- Split(cc, if_true, if_false, NULL); |
+ Split(cc, if_true, if_false, fall_through); |
} |
} |
@@ -3086,12 +3089,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); |
__ cmp(eax, Factory::null_value()); |
if (expr->is_strict()) { |
- Split(equal, if_true, if_false, NULL); |
+ Split(equal, if_true, if_false, fall_through); |
} else { |
__ j(equal, if_true); |
__ cmp(eax, Factory::undefined_value()); |
@@ -3102,7 +3107,7 @@ |
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
__ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); |
__ test(edx, 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); |
} |