| Index: src/arm/full-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/full-codegen-arm.cc (revision 5336)
|
| +++ src/arm/full-codegen-arm.cc (working copy)
|
| @@ -269,7 +269,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;
|
| }
|
| }
|
| @@ -332,7 +332,7 @@
|
|
|
| case Expression::kTest:
|
| __ pop(result_register());
|
| - DoTest(true_label_, false_label_, NULL);
|
| + DoTest(true_label_, false_label_, fall_through_);
|
| break;
|
| }
|
| }
|
| @@ -367,36 +367,12 @@
|
| case Expression::kTest:
|
| __ 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) {
|
| @@ -462,7 +438,11 @@
|
| break;
|
| }
|
| case Expression::kTest:
|
| - __ b(flag ? true_label_ : false_label_);
|
| + if (flag) {
|
| + if (true_label_ != fall_through_) __ b(true_label_);
|
| + } else {
|
| + if (false_label_ != fall_through_) __ b(false_label_);
|
| + }
|
| break;
|
| }
|
| }
|
| @@ -1735,7 +1715,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);
|
|
|
| __ BranchOnSmi(r0, if_true);
|
| __ b(if_false);
|
| @@ -1752,10 +1734,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);
|
|
|
| __ tst(r0, Operand(kSmiTagMask | 0x80000000));
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1769,7 +1753,10 @@
|
| 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);
|
| +
|
| __ BranchOnSmi(r0, if_false);
|
| __ LoadRoot(ip, Heap::kNullValueRootIndex);
|
| __ cmp(r0, ip);
|
| @@ -1783,7 +1770,7 @@
|
| __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
|
| __ b(lt, if_false);
|
| __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
|
| - Split(le, if_true, if_false, NULL);
|
| + Split(le, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1797,11 +1784,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);
|
|
|
| __ BranchOnSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
|
| - Split(ge, if_true, if_false, NULL);
|
| + Split(ge, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1815,13 +1804,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);
|
|
|
| __ BranchOnSmi(r0, if_false);
|
| __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
| __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
|
| __ tst(r1, Operand(1 << Map::kIsUndetectable));
|
| - Split(ne, if_true, if_false, NULL);
|
| + Split(ne, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1837,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
|
| @@ -1855,11 +1848,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);
|
|
|
| __ BranchOnSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1873,11 +1868,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);
|
|
|
| __ BranchOnSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1891,11 +1888,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);
|
|
|
| __ BranchOnSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1908,7 +1907,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.
|
| __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| @@ -1924,7 +1925,7 @@
|
| __ bind(&check_frame_marker);
|
| __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
|
| __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -1940,11 +1941,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(r1);
|
| __ cmp(r0, r1);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
|
|
| Apply(context_, if_true, if_false);
|
| }
|
| @@ -2617,12 +2620,12 @@
|
| 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 +2982,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;
|
| }
|
| @@ -2998,7 +3003,7 @@
|
| __ InvokeBuiltin(Builtins::IN, CALL_JS);
|
| __ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
| __ cmp(r0, ip);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
| break;
|
|
|
| case Token::INSTANCEOF: {
|
| @@ -3007,7 +3012,7 @@
|
| __ CallStub(&stub);
|
| // The stub returns 0 for true.
|
| __ tst(r0, r0);
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
| break;
|
| }
|
|
|
| @@ -3062,7 +3067,7 @@
|
| CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0);
|
| __ CallStub(&stub);
|
| __ cmp(r0, Operand(0));
|
| - Split(cc, if_true, if_false, NULL);
|
| + Split(cc, if_true, if_false, fall_through);
|
| }
|
| }
|
|
|
| @@ -3077,13 +3082,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);
|
|
|
| VisitForValue(expr->expression(), kAccumulator);
|
| __ LoadRoot(r1, Heap::kNullValueRootIndex);
|
| __ cmp(r0, r1);
|
| if (expr->is_strict()) {
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
| } else {
|
| __ b(eq, if_true);
|
| __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
|
| @@ -3096,7 +3103,7 @@
|
| __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
|
| __ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
|
| __ cmp(r1, Operand(1 << Map::kIsUndetectable));
|
| - Split(eq, if_true, if_false, NULL);
|
| + Split(eq, if_true, if_false, fall_through);
|
| }
|
| Apply(context_, if_true, if_false);
|
| }
|
|
|