| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 PredictableCodeSizeScope predictable(masm_, -1); | 461 PredictableCodeSizeScope predictable(masm_, -1); |
| 462 __ LeaveFrame(StackFrame::JAVA_SCRIPT); | 462 __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
| 463 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | 463 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); |
| 464 __ add(sp, sp, Operand(sp_delta)); | 464 __ add(sp, sp, Operand(sp_delta)); |
| 465 __ Jump(lr); | 465 __ Jump(lr); |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 } | 469 } |
| 470 | 470 |
| 471 void FullCodeGenerator::RestoreContext() { |
| 472 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 473 } |
| 471 | 474 |
| 472 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 475 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 473 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 476 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 474 codegen()->GetVar(result_register(), var); | 477 codegen()->GetVar(result_register(), var); |
| 475 codegen()->PushOperand(result_register()); | 478 codegen()->PushOperand(result_register()); |
| 476 } | 479 } |
| 477 | 480 |
| 478 | 481 |
| 479 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 482 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 480 } | 483 } |
| (...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1414 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1412 __ mov(r1, Operand(constant_properties)); | 1415 __ mov(r1, Operand(constant_properties)); |
| 1413 int flags = expr->ComputeFlags(); | 1416 int flags = expr->ComputeFlags(); |
| 1414 __ mov(r0, Operand(Smi::FromInt(flags))); | 1417 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1415 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1418 if (MustCreateObjectLiteralWithRuntime(expr)) { |
| 1416 __ Push(r3, r2, r1, r0); | 1419 __ Push(r3, r2, r1, r0); |
| 1417 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1420 __ CallRuntime(Runtime::kCreateObjectLiteral); |
| 1418 } else { | 1421 } else { |
| 1419 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1422 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
| 1420 __ CallStub(&stub); | 1423 __ CallStub(&stub); |
| 1421 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1424 RestoreContext(); |
| 1422 } | 1425 } |
| 1423 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1426 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1424 | 1427 |
| 1425 // If result_saved is true the result is on top of the stack. If | 1428 // If result_saved is true the result is on top of the stack. If |
| 1426 // result_saved is false the result is in r0. | 1429 // result_saved is false the result is in r0. |
| 1427 bool result_saved = false; | 1430 bool result_saved = false; |
| 1428 | 1431 |
| 1429 AccessorTable accessor_table(zone()); | 1432 AccessorTable accessor_table(zone()); |
| 1430 int property_index = 0; | 1433 int property_index = 0; |
| 1431 for (; property_index < expr->properties()->length(); property_index++) { | 1434 for (; property_index < expr->properties()->length(); property_index++) { |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1859 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 1862 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
| 1860 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 1863 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
| 1861 __ mov(r1, cp); | 1864 __ mov(r1, cp); |
| 1862 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 1865 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
| 1863 kLRHasBeenSaved, kDontSaveFPRegs); | 1866 kLRHasBeenSaved, kDontSaveFPRegs); |
| 1864 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1867 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 1865 __ cmp(sp, r1); | 1868 __ cmp(sp, r1); |
| 1866 __ b(eq, &post_runtime); | 1869 __ b(eq, &post_runtime); |
| 1867 __ push(r0); // generator object | 1870 __ push(r0); // generator object |
| 1868 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1871 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 1869 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1872 RestoreContext(); |
| 1870 __ bind(&post_runtime); | 1873 __ bind(&post_runtime); |
| 1871 PopOperand(result_register()); | 1874 PopOperand(result_register()); |
| 1872 EmitReturnSequence(); | 1875 EmitReturnSequence(); |
| 1873 | 1876 |
| 1874 __ bind(&resume); | 1877 __ bind(&resume); |
| 1875 context()->Plug(result_register()); | 1878 context()->Plug(result_register()); |
| 1876 } | 1879 } |
| 1877 | 1880 |
| 1878 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1881 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| 1879 OperandStackDepthIncrement(2); | 1882 OperandStackDepthIncrement(2); |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2520 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2523 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
| 2521 .code(); | 2524 .code(); |
| 2522 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2525 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); |
| 2523 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2526 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2524 // Don't assign a type feedback id to the IC, since type feedback is provided | 2527 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 2525 // by the vector above. | 2528 // by the vector above. |
| 2526 CallIC(ic); | 2529 CallIC(ic); |
| 2527 OperandStackDepthDecrement(arg_count + 1); | 2530 OperandStackDepthDecrement(arg_count + 1); |
| 2528 | 2531 |
| 2529 RecordJSReturnSite(expr); | 2532 RecordJSReturnSite(expr); |
| 2530 // Restore context register. | 2533 RestoreContext(); |
| 2531 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 2532 context()->DropAndPlug(1, r0); | 2534 context()->DropAndPlug(1, r0); |
| 2533 } | 2535 } |
| 2534 | 2536 |
| 2535 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2537 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
| 2536 int arg_count = expr->arguments()->length(); | 2538 int arg_count = expr->arguments()->length(); |
| 2537 // r4: copy of the first argument or undefined if it doesn't exist. | 2539 // r4: copy of the first argument or undefined if it doesn't exist. |
| 2538 if (arg_count > 0) { | 2540 if (arg_count > 0) { |
| 2539 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize)); | 2541 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize)); |
| 2540 } else { | 2542 } else { |
| 2541 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); | 2543 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 | 2630 |
| 2629 // Record source position for debugger. | 2631 // Record source position for debugger. |
| 2630 SetCallPosition(expr); | 2632 SetCallPosition(expr); |
| 2631 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2633 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2632 __ mov(r0, Operand(arg_count)); | 2634 __ mov(r0, Operand(arg_count)); |
| 2633 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2635 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 2634 expr->tail_call_mode()), | 2636 expr->tail_call_mode()), |
| 2635 RelocInfo::CODE_TARGET); | 2637 RelocInfo::CODE_TARGET); |
| 2636 OperandStackDepthDecrement(arg_count + 1); | 2638 OperandStackDepthDecrement(arg_count + 1); |
| 2637 RecordJSReturnSite(expr); | 2639 RecordJSReturnSite(expr); |
| 2638 // Restore context register. | 2640 RestoreContext(); |
| 2639 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 2640 context()->DropAndPlug(1, r0); | 2641 context()->DropAndPlug(1, r0); |
| 2641 } | 2642 } |
| 2642 | 2643 |
| 2643 | 2644 |
| 2644 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2645 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| 2645 Comment cmnt(masm_, "[ CallNew"); | 2646 Comment cmnt(masm_, "[ CallNew"); |
| 2646 // According to ECMA-262, section 11.2.2, page 44, the function | 2647 // According to ECMA-262, section 11.2.2, page 44, the function |
| 2647 // expression in new calls must be evaluated before the | 2648 // expression in new calls must be evaluated before the |
| 2648 // arguments. | 2649 // arguments. |
| 2649 | 2650 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2669 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2670 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2670 | 2671 |
| 2671 // Record call targets in unoptimized code. | 2672 // Record call targets in unoptimized code. |
| 2672 __ EmitLoadTypeFeedbackVector(r2); | 2673 __ EmitLoadTypeFeedbackVector(r2); |
| 2673 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); | 2674 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); |
| 2674 | 2675 |
| 2675 CallConstructStub stub(isolate()); | 2676 CallConstructStub stub(isolate()); |
| 2676 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2677 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2677 OperandStackDepthDecrement(arg_count + 1); | 2678 OperandStackDepthDecrement(arg_count + 1); |
| 2678 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2679 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2679 // Restore context register. | 2680 RestoreContext(); |
| 2680 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 2681 context()->Plug(r0); | 2681 context()->Plug(r0); |
| 2682 } | 2682 } |
| 2683 | 2683 |
| 2684 | 2684 |
| 2685 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2685 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
| 2686 SuperCallReference* super_call_ref = | 2686 SuperCallReference* super_call_ref = |
| 2687 expr->expression()->AsSuperCallReference(); | 2687 expr->expression()->AsSuperCallReference(); |
| 2688 DCHECK_NOT_NULL(super_call_ref); | 2688 DCHECK_NOT_NULL(super_call_ref); |
| 2689 | 2689 |
| 2690 // Push the super constructor target on the stack (may be null, | 2690 // Push the super constructor target on the stack (may be null, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2713 __ mov(r3, result_register()); | 2713 __ mov(r3, result_register()); |
| 2714 | 2714 |
| 2715 // Load function and argument count into r1 and r0. | 2715 // Load function and argument count into r1 and r0. |
| 2716 __ mov(r0, Operand(arg_count)); | 2716 __ mov(r0, Operand(arg_count)); |
| 2717 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2717 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2718 | 2718 |
| 2719 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2719 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2720 OperandStackDepthDecrement(arg_count + 1); | 2720 OperandStackDepthDecrement(arg_count + 1); |
| 2721 | 2721 |
| 2722 RecordJSReturnSite(expr); | 2722 RecordJSReturnSite(expr); |
| 2723 | 2723 RestoreContext(); |
| 2724 // Restore context register. | |
| 2725 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 2726 context()->Plug(r0); | 2724 context()->Plug(r0); |
| 2727 } | 2725 } |
| 2728 | 2726 |
| 2729 | 2727 |
| 2730 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2728 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2731 ZoneList<Expression*>* args = expr->arguments(); | 2729 ZoneList<Expression*>* args = expr->arguments(); |
| 2732 DCHECK(args->length() == 1); | 2730 DCHECK(args->length() == 1); |
| 2733 | 2731 |
| 2734 VisitForAccumulatorValue(args->at(0)); | 2732 VisitForAccumulatorValue(args->at(0)); |
| 2735 | 2733 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 VisitForStackValue(arg); | 3109 VisitForStackValue(arg); |
| 3112 } | 3110 } |
| 3113 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3111 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3114 // Move target to r1. | 3112 // Move target to r1. |
| 3115 int const argc = args->length() - 2; | 3113 int const argc = args->length() - 2; |
| 3116 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); | 3114 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); |
| 3117 // Call the target. | 3115 // Call the target. |
| 3118 __ mov(r0, Operand(argc)); | 3116 __ mov(r0, Operand(argc)); |
| 3119 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3117 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3120 OperandStackDepthDecrement(argc + 1); | 3118 OperandStackDepthDecrement(argc + 1); |
| 3121 // Restore context register. | 3119 RestoreContext(); |
| 3122 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 3123 // Discard the function left on TOS. | 3120 // Discard the function left on TOS. |
| 3124 context()->DropAndPlug(1, r0); | 3121 context()->DropAndPlug(1, r0); |
| 3125 } | 3122 } |
| 3126 | 3123 |
| 3127 | 3124 |
| 3128 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3125 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3129 ZoneList<Expression*>* args = expr->arguments(); | 3126 ZoneList<Expression*>* args = expr->arguments(); |
| 3130 VisitForAccumulatorValue(args->at(0)); | 3127 VisitForAccumulatorValue(args->at(0)); |
| 3131 | 3128 |
| 3132 Label materialize_true, materialize_false; | 3129 Label materialize_true, materialize_false; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3229 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3226 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 3230 ZoneList<Expression*>* args = expr->arguments(); | 3227 ZoneList<Expression*>* args = expr->arguments(); |
| 3231 int arg_count = args->length(); | 3228 int arg_count = args->length(); |
| 3232 | 3229 |
| 3233 SetCallPosition(expr); | 3230 SetCallPosition(expr); |
| 3234 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3231 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3235 __ mov(r0, Operand(arg_count)); | 3232 __ mov(r0, Operand(arg_count)); |
| 3236 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3233 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 3237 RelocInfo::CODE_TARGET); | 3234 RelocInfo::CODE_TARGET); |
| 3238 OperandStackDepthDecrement(arg_count + 1); | 3235 OperandStackDepthDecrement(arg_count + 1); |
| 3239 | 3236 RestoreContext(); |
| 3240 // Restore context register. | |
| 3241 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 3242 } | 3237 } |
| 3243 | 3238 |
| 3244 | 3239 |
| 3245 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3240 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 3246 switch (expr->op()) { | 3241 switch (expr->op()) { |
| 3247 case Token::DELETE: { | 3242 case Token::DELETE: { |
| 3248 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3243 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
| 3249 Property* property = expr->expression()->AsProperty(); | 3244 Property* property = expr->expression()->AsProperty(); |
| 3250 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3245 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 3251 | 3246 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3697 Label* fall_through = NULL; | 3692 Label* fall_through = NULL; |
| 3698 context()->PrepareTest(&materialize_true, &materialize_false, | 3693 context()->PrepareTest(&materialize_true, &materialize_false, |
| 3699 &if_true, &if_false, &fall_through); | 3694 &if_true, &if_false, &fall_through); |
| 3700 | 3695 |
| 3701 Token::Value op = expr->op(); | 3696 Token::Value op = expr->op(); |
| 3702 VisitForStackValue(expr->left()); | 3697 VisitForStackValue(expr->left()); |
| 3703 switch (op) { | 3698 switch (op) { |
| 3704 case Token::IN: | 3699 case Token::IN: |
| 3705 VisitForStackValue(expr->right()); | 3700 VisitForStackValue(expr->right()); |
| 3706 SetExpressionPosition(expr); | 3701 SetExpressionPosition(expr); |
| 3707 CallRuntimeWithOperands(Runtime::kHasProperty); | 3702 EmitHasProperty(); |
| 3708 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3703 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 3709 __ CompareRoot(r0, Heap::kTrueValueRootIndex); | 3704 __ CompareRoot(r0, Heap::kTrueValueRootIndex); |
| 3710 Split(eq, if_true, if_false, fall_through); | 3705 Split(eq, if_true, if_false, fall_through); |
| 3711 break; | 3706 break; |
| 3712 | 3707 |
| 3713 case Token::INSTANCEOF: { | 3708 case Token::INSTANCEOF: { |
| 3714 VisitForAccumulatorValue(expr->right()); | 3709 VisitForAccumulatorValue(expr->right()); |
| 3715 SetExpressionPosition(expr); | 3710 SetExpressionPosition(expr); |
| 3716 PopOperand(r1); | 3711 PopOperand(r1); |
| 3717 InstanceOfStub stub(isolate()); | 3712 InstanceOfStub stub(isolate()); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4030 DCHECK(interrupt_address == | 4025 DCHECK(interrupt_address == |
| 4031 isolate->builtins()->OnStackReplacement()->entry()); | 4026 isolate->builtins()->OnStackReplacement()->entry()); |
| 4032 return ON_STACK_REPLACEMENT; | 4027 return ON_STACK_REPLACEMENT; |
| 4033 } | 4028 } |
| 4034 | 4029 |
| 4035 | 4030 |
| 4036 } // namespace internal | 4031 } // namespace internal |
| 4037 } // namespace v8 | 4032 } // namespace v8 |
| 4038 | 4033 |
| 4039 #endif // V8_TARGET_ARCH_ARM | 4034 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |