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 |