| 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);
|
| }
|
|
|