| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); | 499 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); |
| 500 __ Add(current_sp, current_sp, ip0); | 500 __ Add(current_sp, current_sp, ip0); |
| 501 __ Ret(); | 501 __ Ret(); |
| 502 int32_t arg_count = info_->scope()->num_parameters() + 1; | 502 int32_t arg_count = info_->scope()->num_parameters() + 1; |
| 503 __ dc64(kXRegSize * arg_count); | 503 __ dc64(kXRegSize * arg_count); |
| 504 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 504 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 505 } | 505 } |
| 506 } | 506 } |
| 507 | 507 |
| 508 | 508 |
| 509 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 510 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 511 } |
| 512 |
| 513 |
| 514 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 515 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 516 codegen()->GetVar(result_register(), var); |
| 517 } |
| 518 |
| 519 |
| 509 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 520 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 510 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 521 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 511 codegen()->GetVar(result_register(), var); | 522 codegen()->GetVar(result_register(), var); |
| 512 __ Push(result_register()); | 523 __ Push(result_register()); |
| 513 } | 524 } |
| 514 | 525 |
| 515 | 526 |
| 527 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 528 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 529 // For simplicity we always test the accumulator register. |
| 530 codegen()->GetVar(result_register(), var); |
| 531 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 532 codegen()->DoTest(this); |
| 533 } |
| 534 |
| 535 |
| 516 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 536 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 517 // Root values have no side effects. | 537 // Root values have no side effects. |
| 518 } | 538 } |
| 519 | 539 |
| 520 | 540 |
| 521 void FullCodeGenerator::AccumulatorValueContext::Plug( | 541 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 522 Heap::RootListIndex index) const { | 542 Heap::RootListIndex index) const { |
| 523 __ LoadRoot(result_register(), index); | 543 __ LoadRoot(result_register(), index); |
| 524 } | 544 } |
| 525 | 545 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 683 } |
| 664 | 684 |
| 665 | 685 |
| 666 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 686 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 667 Label* materialize_false) const { | 687 Label* materialize_false) const { |
| 668 DCHECK(materialize_true == true_label_); | 688 DCHECK(materialize_true == true_label_); |
| 669 DCHECK(materialize_false == false_label_); | 689 DCHECK(materialize_false == false_label_); |
| 670 } | 690 } |
| 671 | 691 |
| 672 | 692 |
| 693 void FullCodeGenerator::EffectContext::Plug(bool flag) const { |
| 694 } |
| 695 |
| 696 |
| 673 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 697 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 674 Heap::RootListIndex value_root_index = | 698 Heap::RootListIndex value_root_index = |
| 675 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 699 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 676 __ LoadRoot(result_register(), value_root_index); | 700 __ LoadRoot(result_register(), value_root_index); |
| 677 } | 701 } |
| 678 | 702 |
| 679 | 703 |
| 680 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 704 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 681 Heap::RootListIndex value_root_index = | 705 Heap::RootListIndex value_root_index = |
| 682 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 706 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 __ Push(cp, x2, x1); | 960 __ Push(cp, x2, x1); |
| 937 // Push initial value for function declaration. | 961 // Push initial value for function declaration. |
| 938 VisitForStackValue(declaration->fun()); | 962 VisitForStackValue(declaration->fun()); |
| 939 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 963 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 940 break; | 964 break; |
| 941 } | 965 } |
| 942 } | 966 } |
| 943 } | 967 } |
| 944 | 968 |
| 945 | 969 |
| 970 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 971 VariableProxy* proxy = declaration->proxy(); |
| 972 Variable* variable = proxy->var(); |
| 973 switch (variable->location()) { |
| 974 case VariableLocation::GLOBAL: |
| 975 case VariableLocation::UNALLOCATED: |
| 976 // TODO(rossberg) |
| 977 break; |
| 978 |
| 979 case VariableLocation::CONTEXT: { |
| 980 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 981 EmitDebugCheckDeclarationContext(variable); |
| 982 // TODO(rossberg) |
| 983 break; |
| 984 } |
| 985 |
| 986 case VariableLocation::PARAMETER: |
| 987 case VariableLocation::LOCAL: |
| 988 case VariableLocation::LOOKUP: |
| 989 UNREACHABLE(); |
| 990 } |
| 991 } |
| 992 |
| 993 |
| 994 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 995 // TODO(rossberg) |
| 996 } |
| 997 |
| 998 |
| 946 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 999 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 947 // Call the runtime to declare the globals. | 1000 // Call the runtime to declare the globals. |
| 948 __ Mov(x11, Operand(pairs)); | 1001 __ Mov(x11, Operand(pairs)); |
| 949 Register flags = xzr; | 1002 Register flags = xzr; |
| 950 if (Smi::FromInt(DeclareGlobalsFlags())) { | 1003 if (Smi::FromInt(DeclareGlobalsFlags())) { |
| 951 flags = x10; | 1004 flags = x10; |
| 952 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); | 1005 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); |
| 953 } | 1006 } |
| 954 __ Push(cp, x11, flags); | 1007 __ Push(cp, x11, flags); |
| 955 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1008 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 __ Mov(x11, Operand(info)); | 1311 __ Mov(x11, Operand(info)); |
| 1259 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex | 1312 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex |
| 1260 : Heap::kFalseValueRootIndex); | 1313 : Heap::kFalseValueRootIndex); |
| 1261 __ Push(cp, x11, x10); | 1314 __ Push(cp, x11, x10); |
| 1262 __ CallRuntime(Runtime::kNewClosure, 3); | 1315 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1263 } | 1316 } |
| 1264 context()->Plug(x0); | 1317 context()->Plug(x0); |
| 1265 } | 1318 } |
| 1266 | 1319 |
| 1267 | 1320 |
| 1321 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1322 Comment cmnt(masm_, "[ VariableProxy"); |
| 1323 EmitVariableLoad(expr); |
| 1324 } |
| 1325 |
| 1326 |
| 1268 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1327 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1269 int offset, | 1328 int offset, |
| 1270 FeedbackVectorICSlot slot) { | 1329 FeedbackVectorICSlot slot) { |
| 1271 if (NeedsHomeObject(initializer)) { | 1330 if (NeedsHomeObject(initializer)) { |
| 1272 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1331 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1273 __ Mov(StoreDescriptor::NameRegister(), | 1332 __ Mov(StoreDescriptor::NameRegister(), |
| 1274 Operand(isolate()->factory()->home_object_symbol())); | 1333 Operand(isolate()->factory()->home_object_symbol())); |
| 1275 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1334 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
| 1276 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1335 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1277 CallStoreIC(); | 1336 CallStoreIC(); |
| (...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3550 __ Bind(&null); | 3609 __ Bind(&null); |
| 3551 __ LoadRoot(x0, Heap::kNullValueRootIndex); | 3610 __ LoadRoot(x0, Heap::kNullValueRootIndex); |
| 3552 | 3611 |
| 3553 // All done. | 3612 // All done. |
| 3554 __ Bind(&done); | 3613 __ Bind(&done); |
| 3555 | 3614 |
| 3556 context()->Plug(x0); | 3615 context()->Plug(x0); |
| 3557 } | 3616 } |
| 3558 | 3617 |
| 3559 | 3618 |
| 3619 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3620 // Load the arguments on the stack and call the stub. |
| 3621 SubStringStub stub(isolate()); |
| 3622 ZoneList<Expression*>* args = expr->arguments(); |
| 3623 DCHECK(args->length() == 3); |
| 3624 VisitForStackValue(args->at(0)); |
| 3625 VisitForStackValue(args->at(1)); |
| 3626 VisitForStackValue(args->at(2)); |
| 3627 __ CallStub(&stub); |
| 3628 context()->Plug(x0); |
| 3629 } |
| 3630 |
| 3631 |
| 3632 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3633 // Load the arguments on the stack and call the stub. |
| 3634 RegExpExecStub stub(isolate()); |
| 3635 ZoneList<Expression*>* args = expr->arguments(); |
| 3636 DCHECK(args->length() == 4); |
| 3637 VisitForStackValue(args->at(0)); |
| 3638 VisitForStackValue(args->at(1)); |
| 3639 VisitForStackValue(args->at(2)); |
| 3640 VisitForStackValue(args->at(3)); |
| 3641 __ CallStub(&stub); |
| 3642 context()->Plug(x0); |
| 3643 } |
| 3644 |
| 3645 |
| 3560 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3646 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3561 ASM_LOCATION("FullCodeGenerator::EmitValueOf"); | 3647 ASM_LOCATION("FullCodeGenerator::EmitValueOf"); |
| 3562 ZoneList<Expression*>* args = expr->arguments(); | 3648 ZoneList<Expression*>* args = expr->arguments(); |
| 3563 DCHECK(args->length() == 1); | 3649 DCHECK(args->length() == 1); |
| 3564 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3650 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3565 | 3651 |
| 3566 Label done; | 3652 Label done; |
| 3567 // If the object is a smi return the object. | 3653 // If the object is a smi return the object. |
| 3568 __ JumpIfSmi(x0, &done); | 3654 __ JumpIfSmi(x0, &done); |
| 3569 // If the object is not a value type, return the object. | 3655 // If the object is not a value type, return the object. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3689 } | 3775 } |
| 3690 | 3776 |
| 3691 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); | 3777 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
| 3692 __ SmiUntag(value); | 3778 __ SmiUntag(value); |
| 3693 __ SmiUntag(index); | 3779 __ SmiUntag(index); |
| 3694 __ Strh(value, MemOperand(scratch, index, LSL, 1)); | 3780 __ Strh(value, MemOperand(scratch, index, LSL, 1)); |
| 3695 context()->Plug(string); | 3781 context()->Plug(string); |
| 3696 } | 3782 } |
| 3697 | 3783 |
| 3698 | 3784 |
| 3785 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 3786 // Load the arguments on the stack and call the MathPow stub. |
| 3787 ZoneList<Expression*>* args = expr->arguments(); |
| 3788 DCHECK(args->length() == 2); |
| 3789 VisitForStackValue(args->at(0)); |
| 3790 VisitForStackValue(args->at(1)); |
| 3791 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 3792 __ CallStub(&stub); |
| 3793 context()->Plug(x0); |
| 3794 } |
| 3795 |
| 3796 |
| 3699 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3797 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3700 ZoneList<Expression*>* args = expr->arguments(); | 3798 ZoneList<Expression*>* args = expr->arguments(); |
| 3701 DCHECK(args->length() == 2); | 3799 DCHECK(args->length() == 2); |
| 3702 VisitForStackValue(args->at(0)); // Load the object. | 3800 VisitForStackValue(args->at(0)); // Load the object. |
| 3703 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3801 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 3704 __ Pop(x1); | 3802 __ Pop(x1); |
| 3705 // x0 = value. | 3803 // x0 = value. |
| 3706 // x1 = object. | 3804 // x1 = object. |
| 3707 | 3805 |
| 3708 Label done; | 3806 Label done; |
| 3709 // If the object is a smi, return the value. | 3807 // If the object is a smi, return the value. |
| 3710 __ JumpIfSmi(x1, &done); | 3808 __ JumpIfSmi(x1, &done); |
| 3711 | 3809 |
| 3712 // If the object is not a value type, return the value. | 3810 // If the object is not a value type, return the value. |
| 3713 __ JumpIfNotObjectType(x1, x10, x11, JS_VALUE_TYPE, &done); | 3811 __ JumpIfNotObjectType(x1, x10, x11, JS_VALUE_TYPE, &done); |
| 3714 | 3812 |
| 3715 // Store the value. | 3813 // Store the value. |
| 3716 __ Str(x0, FieldMemOperand(x1, JSValue::kValueOffset)); | 3814 __ Str(x0, FieldMemOperand(x1, JSValue::kValueOffset)); |
| 3717 // Update the write barrier. Save the value as it will be | 3815 // Update the write barrier. Save the value as it will be |
| 3718 // overwritten by the write barrier code and is needed afterward. | 3816 // overwritten by the write barrier code and is needed afterward. |
| 3719 __ Mov(x10, x0); | 3817 __ Mov(x10, x0); |
| 3720 __ RecordWriteField( | 3818 __ RecordWriteField( |
| 3721 x1, JSValue::kValueOffset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 3819 x1, JSValue::kValueOffset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
| 3722 | 3820 |
| 3723 __ Bind(&done); | 3821 __ Bind(&done); |
| 3724 context()->Plug(x0); | 3822 context()->Plug(x0); |
| 3725 } | 3823 } |
| 3726 | 3824 |
| 3825 |
| 3826 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 3827 ZoneList<Expression*>* args = expr->arguments(); |
| 3828 DCHECK_EQ(args->length(), 1); |
| 3829 |
| 3830 // Load the argument into x0 and call the stub. |
| 3831 VisitForAccumulatorValue(args->at(0)); |
| 3832 |
| 3833 NumberToStringStub stub(isolate()); |
| 3834 __ CallStub(&stub); |
| 3835 context()->Plug(x0); |
| 3836 } |
| 3837 |
| 3727 | 3838 |
| 3728 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 3839 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 3729 ZoneList<Expression*>* args = expr->arguments(); | 3840 ZoneList<Expression*>* args = expr->arguments(); |
| 3730 DCHECK(args->length() == 1); | 3841 DCHECK(args->length() == 1); |
| 3731 | 3842 |
| 3732 VisitForAccumulatorValue(args->at(0)); | 3843 VisitForAccumulatorValue(args->at(0)); |
| 3733 | 3844 |
| 3734 Label done; | 3845 Label done; |
| 3735 Register code = x0; | 3846 Register code = x0; |
| 3736 Register result = x1; | 3847 Register result = x1; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3846 VisitForStackValue(args->at(0)); | 3957 VisitForStackValue(args->at(0)); |
| 3847 VisitForAccumulatorValue(args->at(1)); | 3958 VisitForAccumulatorValue(args->at(1)); |
| 3848 | 3959 |
| 3849 __ Pop(x1); | 3960 __ Pop(x1); |
| 3850 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3961 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 3851 __ CallStub(&stub); | 3962 __ CallStub(&stub); |
| 3852 | 3963 |
| 3853 context()->Plug(x0); | 3964 context()->Plug(x0); |
| 3854 } | 3965 } |
| 3855 | 3966 |
| 3967 |
| 3968 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3969 ZoneList<Expression*>* args = expr->arguments(); |
| 3970 DCHECK_EQ(2, args->length()); |
| 3971 VisitForStackValue(args->at(0)); |
| 3972 VisitForStackValue(args->at(1)); |
| 3973 |
| 3974 StringCompareStub stub(isolate()); |
| 3975 __ CallStub(&stub); |
| 3976 context()->Plug(x0); |
| 3977 } |
| 3978 |
| 3856 | 3979 |
| 3857 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3980 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3858 ASM_LOCATION("FullCodeGenerator::EmitCallFunction"); | 3981 ASM_LOCATION("FullCodeGenerator::EmitCallFunction"); |
| 3859 ZoneList<Expression*>* args = expr->arguments(); | 3982 ZoneList<Expression*>* args = expr->arguments(); |
| 3860 DCHECK(args->length() >= 2); | 3983 DCHECK(args->length() >= 2); |
| 3861 | 3984 |
| 3862 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3985 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 3863 for (int i = 0; i < arg_count + 1; i++) { | 3986 for (int i = 0; i < arg_count + 1; i++) { |
| 3864 VisitForStackValue(args->at(i)); | 3987 VisitForStackValue(args->at(i)); |
| 3865 } | 3988 } |
| (...skipping 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5440 } | 5563 } |
| 5441 | 5564 |
| 5442 return INTERRUPT; | 5565 return INTERRUPT; |
| 5443 } | 5566 } |
| 5444 | 5567 |
| 5445 | 5568 |
| 5446 } // namespace internal | 5569 } // namespace internal |
| 5447 } // namespace v8 | 5570 } // namespace v8 |
| 5448 | 5571 |
| 5449 #endif // V8_TARGET_ARCH_ARM64 | 5572 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |