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