| 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 | |
| 520 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 509 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 521 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 510 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 522 codegen()->GetVar(result_register(), var); | 511 codegen()->GetVar(result_register(), var); |
| 523 __ Push(result_register()); | 512 __ Push(result_register()); |
| 524 } | 513 } |
| 525 | 514 |
| 526 | 515 |
| 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 | |
| 536 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 516 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 537 // Root values have no side effects. | 517 // Root values have no side effects. |
| 538 } | 518 } |
| 539 | 519 |
| 540 | 520 |
| 541 void FullCodeGenerator::AccumulatorValueContext::Plug( | 521 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 542 Heap::RootListIndex index) const { | 522 Heap::RootListIndex index) const { |
| 543 __ LoadRoot(result_register(), index); | 523 __ LoadRoot(result_register(), index); |
| 544 } | 524 } |
| 545 | 525 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 } | 663 } |
| 684 | 664 |
| 685 | 665 |
| 686 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 666 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 687 Label* materialize_false) const { | 667 Label* materialize_false) const { |
| 688 DCHECK(materialize_true == true_label_); | 668 DCHECK(materialize_true == true_label_); |
| 689 DCHECK(materialize_false == false_label_); | 669 DCHECK(materialize_false == false_label_); |
| 690 } | 670 } |
| 691 | 671 |
| 692 | 672 |
| 693 void FullCodeGenerator::EffectContext::Plug(bool flag) const { | |
| 694 } | |
| 695 | |
| 696 | |
| 697 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 673 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 698 Heap::RootListIndex value_root_index = | 674 Heap::RootListIndex value_root_index = |
| 699 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 675 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 700 __ LoadRoot(result_register(), value_root_index); | 676 __ LoadRoot(result_register(), value_root_index); |
| 701 } | 677 } |
| 702 | 678 |
| 703 | 679 |
| 704 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 680 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 705 Heap::RootListIndex value_root_index = | 681 Heap::RootListIndex value_root_index = |
| 706 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 682 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 __ Push(cp, x2, x1); | 936 __ Push(cp, x2, x1); |
| 961 // Push initial value for function declaration. | 937 // Push initial value for function declaration. |
| 962 VisitForStackValue(declaration->fun()); | 938 VisitForStackValue(declaration->fun()); |
| 963 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 939 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 964 break; | 940 break; |
| 965 } | 941 } |
| 966 } | 942 } |
| 967 } | 943 } |
| 968 | 944 |
| 969 | 945 |
| 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 | |
| 999 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 946 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 1000 // Call the runtime to declare the globals. | 947 // Call the runtime to declare the globals. |
| 1001 __ Mov(x11, Operand(pairs)); | 948 __ Mov(x11, Operand(pairs)); |
| 1002 Register flags = xzr; | 949 Register flags = xzr; |
| 1003 if (Smi::FromInt(DeclareGlobalsFlags())) { | 950 if (Smi::FromInt(DeclareGlobalsFlags())) { |
| 1004 flags = x10; | 951 flags = x10; |
| 1005 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); | 952 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); |
| 1006 } | 953 } |
| 1007 __ Push(cp, x11, flags); | 954 __ Push(cp, x11, flags); |
| 1008 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 955 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 __ Mov(x11, Operand(info)); | 1258 __ Mov(x11, Operand(info)); |
| 1312 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex | 1259 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex |
| 1313 : Heap::kFalseValueRootIndex); | 1260 : Heap::kFalseValueRootIndex); |
| 1314 __ Push(cp, x11, x10); | 1261 __ Push(cp, x11, x10); |
| 1315 __ CallRuntime(Runtime::kNewClosure, 3); | 1262 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1316 } | 1263 } |
| 1317 context()->Plug(x0); | 1264 context()->Plug(x0); |
| 1318 } | 1265 } |
| 1319 | 1266 |
| 1320 | 1267 |
| 1321 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | |
| 1322 Comment cmnt(masm_, "[ VariableProxy"); | |
| 1323 EmitVariableLoad(expr); | |
| 1324 } | |
| 1325 | |
| 1326 | |
| 1327 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1268 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1328 int offset, | 1269 int offset, |
| 1329 FeedbackVectorICSlot slot) { | 1270 FeedbackVectorICSlot slot) { |
| 1330 if (NeedsHomeObject(initializer)) { | 1271 if (NeedsHomeObject(initializer)) { |
| 1331 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1272 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1332 __ Mov(StoreDescriptor::NameRegister(), | 1273 __ Mov(StoreDescriptor::NameRegister(), |
| 1333 Operand(isolate()->factory()->home_object_symbol())); | 1274 Operand(isolate()->factory()->home_object_symbol())); |
| 1334 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1275 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
| 1335 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1276 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1336 CallStoreIC(); | 1277 CallStoreIC(); |
| (...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3609 __ Bind(&null); | 3550 __ Bind(&null); |
| 3610 __ LoadRoot(x0, Heap::kNullValueRootIndex); | 3551 __ LoadRoot(x0, Heap::kNullValueRootIndex); |
| 3611 | 3552 |
| 3612 // All done. | 3553 // All done. |
| 3613 __ Bind(&done); | 3554 __ Bind(&done); |
| 3614 | 3555 |
| 3615 context()->Plug(x0); | 3556 context()->Plug(x0); |
| 3616 } | 3557 } |
| 3617 | 3558 |
| 3618 | 3559 |
| 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 | |
| 3646 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3560 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3647 ASM_LOCATION("FullCodeGenerator::EmitValueOf"); | 3561 ASM_LOCATION("FullCodeGenerator::EmitValueOf"); |
| 3648 ZoneList<Expression*>* args = expr->arguments(); | 3562 ZoneList<Expression*>* args = expr->arguments(); |
| 3649 DCHECK(args->length() == 1); | 3563 DCHECK(args->length() == 1); |
| 3650 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3564 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3651 | 3565 |
| 3652 Label done; | 3566 Label done; |
| 3653 // If the object is a smi return the object. | 3567 // If the object is a smi return the object. |
| 3654 __ JumpIfSmi(x0, &done); | 3568 __ JumpIfSmi(x0, &done); |
| 3655 // If the object is not a value type, return the object. | 3569 // If the object is not a value type, return the object. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3775 } | 3689 } |
| 3776 | 3690 |
| 3777 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); | 3691 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
| 3778 __ SmiUntag(value); | 3692 __ SmiUntag(value); |
| 3779 __ SmiUntag(index); | 3693 __ SmiUntag(index); |
| 3780 __ Strh(value, MemOperand(scratch, index, LSL, 1)); | 3694 __ Strh(value, MemOperand(scratch, index, LSL, 1)); |
| 3781 context()->Plug(string); | 3695 context()->Plug(string); |
| 3782 } | 3696 } |
| 3783 | 3697 |
| 3784 | 3698 |
| 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 | |
| 3797 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3699 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3798 ZoneList<Expression*>* args = expr->arguments(); | 3700 ZoneList<Expression*>* args = expr->arguments(); |
| 3799 DCHECK(args->length() == 2); | 3701 DCHECK(args->length() == 2); |
| 3800 VisitForStackValue(args->at(0)); // Load the object. | 3702 VisitForStackValue(args->at(0)); // Load the object. |
| 3801 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3703 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 3802 __ Pop(x1); | 3704 __ Pop(x1); |
| 3803 // x0 = value. | 3705 // x0 = value. |
| 3804 // x1 = object. | 3706 // x1 = object. |
| 3805 | 3707 |
| 3806 Label done; | 3708 Label done; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3958 VisitForAccumulatorValue(args->at(1)); | 3860 VisitForAccumulatorValue(args->at(1)); |
| 3959 | 3861 |
| 3960 __ Pop(x1); | 3862 __ Pop(x1); |
| 3961 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3863 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 3962 __ CallStub(&stub); | 3864 __ CallStub(&stub); |
| 3963 | 3865 |
| 3964 context()->Plug(x0); | 3866 context()->Plug(x0); |
| 3965 } | 3867 } |
| 3966 | 3868 |
| 3967 | 3869 |
| 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 | |
| 3979 | |
| 3980 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3870 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3981 ASM_LOCATION("FullCodeGenerator::EmitCallFunction"); | 3871 ASM_LOCATION("FullCodeGenerator::EmitCallFunction"); |
| 3982 ZoneList<Expression*>* args = expr->arguments(); | 3872 ZoneList<Expression*>* args = expr->arguments(); |
| 3983 DCHECK(args->length() >= 2); | 3873 DCHECK(args->length() >= 2); |
| 3984 | 3874 |
| 3985 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3875 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 3986 for (int i = 0; i < arg_count + 1; i++) { | 3876 for (int i = 0; i < arg_count + 1; i++) { |
| 3987 VisitForStackValue(args->at(i)); | 3877 VisitForStackValue(args->at(i)); |
| 3988 } | 3878 } |
| 3989 VisitForAccumulatorValue(args->last()); // Function. | 3879 VisitForAccumulatorValue(args->last()); // Function. |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5563 } | 5453 } |
| 5564 | 5454 |
| 5565 return INTERRUPT; | 5455 return INTERRUPT; |
| 5566 } | 5456 } |
| 5567 | 5457 |
| 5568 | 5458 |
| 5569 } // namespace internal | 5459 } // namespace internal |
| 5570 } // namespace v8 | 5460 } // namespace v8 |
| 5571 | 5461 |
| 5572 #endif // V8_TARGET_ARCH_ARM64 | 5462 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |