| Index: src/arm/full-codegen-arm.cc
|
| diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
|
| index 3d75c143aa118ff965337a4dce8ffa2a1cca730b..d0c663b4081d77fd0a191727e9ff075dba49cedb 100644
|
| --- a/src/arm/full-codegen-arm.cc
|
| +++ b/src/arm/full-codegen-arm.cc
|
| @@ -394,7 +394,7 @@ void FullCodeGenerator::TestContext::Plug(Variable* var) const {
|
| ASSERT(var->IsStackAllocated() || var->IsContextSlot());
|
| // For simplicity we always test the accumulator register.
|
| codegen()->GetVar(result_register(), var);
|
| - codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
| + codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
|
| codegen()->DoTest(this);
|
| }
|
|
|
| @@ -417,7 +417,7 @@ void FullCodeGenerator::StackValueContext::Plug(
|
|
|
|
|
| void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
|
| - codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
|
| + codegen()->PrepareForBailoutBeforeSplit(condition(),
|
| true,
|
| true_label_,
|
| false_label_);
|
| @@ -452,7 +452,7 @@ void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
|
|
|
|
|
| void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
|
| - codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
|
| + codegen()->PrepareForBailoutBeforeSplit(condition(),
|
| true,
|
| true_label_,
|
| false_label_);
|
| @@ -511,7 +511,7 @@ void FullCodeGenerator::TestContext::DropAndPlug(int count,
|
| // For simplicity we always test the accumulator register.
|
| __ Drop(count);
|
| __ Move(result_register(), reg);
|
| - codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
| + codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
|
| codegen()->DoTest(this);
|
| }
|
|
|
| @@ -578,7 +578,7 @@ void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
|
|
|
|
|
| void FullCodeGenerator::TestContext::Plug(bool flag) const {
|
| - codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
|
| + codegen()->PrepareForBailoutBeforeSplit(condition(),
|
| true,
|
| true_label_,
|
| false_label_);
|
| @@ -681,7 +681,7 @@ void FullCodeGenerator::SetVar(Variable* var,
|
| }
|
|
|
|
|
| -void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
|
| +void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
|
| bool should_normalize,
|
| Label* if_true,
|
| Label* if_false) {
|
| @@ -692,13 +692,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
|
|
|
| Label skip;
|
| if (should_normalize) __ b(&skip);
|
| -
|
| - ForwardBailoutStack* current = forward_bailout_stack_;
|
| - while (current != NULL) {
|
| - PrepareForBailout(current->expr(), state);
|
| - current = current->parent();
|
| - }
|
| -
|
| + PrepareForBailout(expr, TOS_REG);
|
| if (should_normalize) {
|
| __ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
| __ cmp(r0, ip);
|
| @@ -2377,7 +2371,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2389,7 +2384,7 @@ void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
|
| context()->PrepareTest(&materialize_true, &materialize_false,
|
| &if_true, &if_false, &fall_through);
|
|
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| __ tst(r0, Operand(kSmiTagMask));
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| @@ -2397,7 +2392,8 @@ void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2409,7 +2405,7 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
| context()->PrepareTest(&materialize_true, &materialize_false,
|
| &if_true, &if_false, &fall_through);
|
|
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| __ tst(r0, Operand(kSmiTagMask | 0x80000000));
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| @@ -2417,7 +2413,8 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2442,14 +2439,15 @@ void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
|
| __ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
| __ b(lt, if_false);
|
| __ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(le, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2463,14 +2461,15 @@ void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
|
|
|
| __ JumpIfSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(ge, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2486,7 +2485,7 @@ void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
|
| __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
| __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
|
| __ tst(r1, Operand(1 << Map::kIsUndetectable));
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(ne, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| @@ -2494,8 +2493,8 @@ void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
|
|
|
|
|
| void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
|
| - ZoneList<Expression*>* args) {
|
| -
|
| + CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2574,12 +2573,13 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
|
| __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset));
|
| __ jmp(if_true);
|
|
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2593,14 +2593,15 @@ void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
|
|
|
| __ JumpIfSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2614,14 +2615,15 @@ void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
|
|
|
| __ JumpIfSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -2635,7 +2637,7 @@ void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
|
|
|
| __ JumpIfSmi(r0, if_false);
|
| __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| @@ -2643,8 +2645,8 @@ void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
|
|
|
|
|
|
|
| -void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
|
| - ASSERT(args->length() == 0);
|
| +void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
| + ASSERT(expr->arguments()->length() == 0);
|
|
|
| Label materialize_true, materialize_false;
|
| Label* if_true = NULL;
|
| @@ -2667,14 +2669,15 @@ void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
|
| __ bind(&check_frame_marker);
|
| __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
|
| __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
|
|
| // Load the two objects into registers and perform the comparison.
|
| @@ -2690,14 +2693,15 @@ void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
|
|
|
| __ pop(r1);
|
| __ cmp(r0, r1);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
|
|
| // ArgumentsAccessStub expects the key in edx and the formal
|
| @@ -2711,9 +2715,8 @@ void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
|
| - ASSERT(args->length() == 0);
|
| -
|
| +void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
|
| + ASSERT(expr->arguments()->length() == 0);
|
| Label exit;
|
| // Get the number of formal parameters.
|
| __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
|
| @@ -2733,7 +2736,8 @@ void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| Label done, null, function, non_function_constructor;
|
|
|
| @@ -2793,7 +2797,7 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitLog(CallRuntime* expr) {
|
| // Conditionally generate a log call.
|
| // Args:
|
| // 0 (literal string): The type of logging (corresponds to the flags).
|
| @@ -2801,6 +2805,7 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
| // 1 (string): Format string. Access the string at argument index 2
|
| // with '%2s' (see Logger::LogRuntime for all the formats).
|
| // 2 (array): Arguments to the format string.
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(args->length(), 3);
|
| if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
|
| VisitForStackValue(args->at(1));
|
| @@ -2814,9 +2819,8 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
|
| - ASSERT(args->length() == 0);
|
| -
|
| +void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
|
| + ASSERT(expr->arguments()->length() == 0);
|
| Label slow_allocate_heapnumber;
|
| Label heapnumber_allocated;
|
|
|
| @@ -2868,9 +2872,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
|
| // Load the arguments on the stack and call the stub.
|
| SubStringStub stub;
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 3);
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
| @@ -2880,9 +2885,10 @@ void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
|
| // Load the arguments on the stack and call the stub.
|
| RegExpExecStub stub;
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 4);
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
| @@ -2893,9 +2899,9 @@ void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| -
|
| VisitForAccumulatorValue(args->at(0)); // Load the object.
|
|
|
| Label done;
|
| @@ -2911,8 +2917,9 @@ void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
|
| // Load the arguments on the stack and call the runtime function.
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
| @@ -2922,9 +2929,9 @@ void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
| -
|
| VisitForStackValue(args->at(0)); // Load the object.
|
| VisitForAccumulatorValue(args->at(1)); // Load the value.
|
| __ pop(r1); // r0 = value. r1 = object.
|
| @@ -2950,9 +2957,9 @@ void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(args->length(), 1);
|
| -
|
| // Load the argument on the stack and call the stub.
|
| VisitForStackValue(args->at(0));
|
|
|
| @@ -2962,9 +2969,9 @@ void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| -
|
| VisitForAccumulatorValue(args->at(0));
|
|
|
| Label done;
|
| @@ -2980,9 +2987,9 @@ void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
| -
|
| VisitForStackValue(args->at(0));
|
| VisitForAccumulatorValue(args->at(1));
|
|
|
| @@ -3027,9 +3034,9 @@ void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
| -
|
| VisitForStackValue(args->at(0));
|
| VisitForAccumulatorValue(args->at(1));
|
|
|
| @@ -3076,9 +3083,9 @@ void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(2, args->length());
|
| -
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
|
|
| @@ -3088,9 +3095,9 @@ void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(2, args->length());
|
| -
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
|
|
| @@ -3100,10 +3107,11 @@ void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
|
| // Load the argument on the stack and call the stub.
|
| TranscendentalCacheStub stub(TranscendentalCache::SIN,
|
| TranscendentalCacheStub::TAGGED);
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| VisitForStackValue(args->at(0));
|
| __ CallStub(&stub);
|
| @@ -3111,10 +3119,11 @@ void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
|
| // Load the argument on the stack and call the stub.
|
| TranscendentalCacheStub stub(TranscendentalCache::COS,
|
| TranscendentalCacheStub::TAGGED);
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| VisitForStackValue(args->at(0));
|
| __ CallStub(&stub);
|
| @@ -3122,10 +3131,11 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
|
| // Load the argument on the stack and call the stub.
|
| TranscendentalCacheStub stub(TranscendentalCache::LOG,
|
| TranscendentalCacheStub::TAGGED);
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| VisitForStackValue(args->at(0));
|
| __ CallStub(&stub);
|
| @@ -3133,8 +3143,9 @@ void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
|
| // Load the argument on the stack and call the runtime function.
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| VisitForStackValue(args->at(0));
|
| __ CallRuntime(Runtime::kMath_sqrt, 1);
|
| @@ -3142,7 +3153,8 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() >= 2);
|
|
|
| int arg_count = args->length() - 2; // 2 ~ receiver and function.
|
| @@ -3161,8 +3173,9 @@ void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
|
| RegExpConstructResultStub stub;
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 3);
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
| @@ -3172,7 +3185,8 @@ void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitSwapElements(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 3);
|
| VisitForStackValue(args->at(0));
|
| VisitForStackValue(args->at(1));
|
| @@ -3269,9 +3283,9 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(2, args->length());
|
| -
|
| ASSERT_NE(NULL, args->at(0)->AsLiteral());
|
| int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
|
|
|
| @@ -3320,7 +3334,8 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT_EQ(2, args->length());
|
|
|
| Register right = r0;
|
| @@ -3360,7 +3375,8 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| VisitForAccumulatorValue(args->at(0));
|
|
|
| Label materialize_true, materialize_false;
|
| @@ -3372,14 +3388,15 @@ void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
|
|
|
| __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
|
| __ tst(r0, Operand(String::kContainsCachedArrayIndexMask));
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Split(eq, if_true, if_false, fall_through);
|
|
|
| context()->Plug(if_true, if_false);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 1);
|
| VisitForAccumulatorValue(args->at(0));
|
|
|
| @@ -3394,12 +3411,12 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
|
| Label bailout, done, one_char_separator, long_separator,
|
| non_trivial_array, not_size_one_array, loop,
|
| empty_separator_loop, one_char_separator_loop,
|
| one_char_separator_loop_entry, long_separator_loop;
|
| -
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| ASSERT(args->length() == 2);
|
| VisitForStackValue(args->at(1));
|
| VisitForAccumulatorValue(args->at(0));
|
| @@ -3727,18 +3744,35 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
| // Unary NOT has no side effects so it's only necessary to visit the
|
| // subexpression. Match the optimizing compiler by not branching.
|
| VisitForEffect(expr->expression());
|
| + } else if (context()->IsTest()) {
|
| + const TestContext* test = TestContext::cast(context());
|
| + // The labels are swapped for the recursive call.
|
| + VisitForControl(expr->expression(),
|
| + test->false_label(),
|
| + test->true_label(),
|
| + test->fall_through());
|
| + context()->Plug(test->true_label(), test->false_label());
|
| } else {
|
| - Label materialize_true, materialize_false;
|
| - Label* if_true = NULL;
|
| - Label* if_false = NULL;
|
| - Label* fall_through = NULL;
|
| -
|
| - // Notice that the labels are swapped.
|
| - context()->PrepareTest(&materialize_true, &materialize_false,
|
| - &if_false, &if_true, &fall_through);
|
| - if (context()->IsTest()) ForwardBailoutToChild(expr);
|
| - VisitForControl(expr->expression(), if_true, if_false, fall_through);
|
| - context()->Plug(if_false, if_true); // Labels swapped.
|
| + // We handle value contexts explicitly rather than simply visiting
|
| + // for control and plugging the control flow into the context,
|
| + // because we need to prepare a pair of extra administrative AST ids
|
| + // for the optimizing compiler.
|
| + ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue());
|
| + Label materialize_true, materialize_false, done;
|
| + VisitForControl(expr->expression(),
|
| + &materialize_false,
|
| + &materialize_true,
|
| + &materialize_true);
|
| + __ bind(&materialize_true);
|
| + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
|
| + __ LoadRoot(r0, Heap::kTrueValueRootIndex);
|
| + if (context()->IsStackValue()) __ push(r0);
|
| + __ jmp(&done);
|
| + __ bind(&materialize_false);
|
| + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
|
| + __ LoadRoot(r0, Heap::kFalseValueRootIndex);
|
| + if (context()->IsStackValue()) __ push(r0);
|
| + __ bind(&done);
|
| }
|
| break;
|
| }
|
| @@ -3997,12 +4031,13 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
| context()->Plug(r0);
|
| } else {
|
| // This expression cannot throw a reference error at the top level.
|
| - VisitInCurrentContext(expr);
|
| + VisitInDuplicateContext(expr);
|
| }
|
| }
|
|
|
|
|
| void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
|
| + Expression* sub_expr,
|
| Handle<String> check) {
|
| Label materialize_true, materialize_false;
|
| Label* if_true = NULL;
|
| @@ -4012,9 +4047,9 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
|
| &if_true, &if_false, &fall_through);
|
|
|
| { AccumulatorValueContext context(this);
|
| - VisitForTypeofValue(expr);
|
| + VisitForTypeofValue(sub_expr);
|
| }
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
|
|
| if (check->Equals(isolate()->heap()->number_symbol())) {
|
| __ JumpIfSmi(r0, if_true);
|
| @@ -4101,7 +4136,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
| case Token::IN:
|
| VisitForStackValue(expr->right());
|
| __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
| + PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
| __ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
| __ cmp(r0, ip);
|
| Split(eq, if_true, if_false, fall_through);
|
| @@ -4111,7 +4146,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
| VisitForStackValue(expr->right());
|
| InstanceofStub stub(InstanceofStub::kNoFlags);
|
| __ CallStub(&stub);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| // The stub returns 0 for true.
|
| __ tst(r0, r0);
|
| Split(eq, if_true, if_false, fall_through);
|
| @@ -4161,7 +4196,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
| Handle<Code> ic = CompareIC::GetUninitialized(op);
|
| __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
| patch_site.EmitPatchInfo();
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| __ cmp(r0, Operand(0));
|
| Split(cond, if_true, if_false, fall_through);
|
| }
|
| @@ -4184,7 +4219,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
|
| &if_true, &if_false, &fall_through);
|
|
|
| VisitForAccumulatorValue(sub_expr);
|
| - PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
| + PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
| Heap::RootListIndex nil_value = nil == kNullValue ?
|
| Heap::kNullValueRootIndex :
|
| Heap::kUndefinedValueRootIndex;
|
|
|