| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 | 465 |
| 466 int arg_count = info_->scope()->num_parameters() + 1; | 466 int arg_count = info_->scope()->num_parameters() + 1; |
| 467 int arguments_bytes = arg_count * kPointerSize; | 467 int arguments_bytes = arg_count * kPointerSize; |
| 468 __ Ret(arguments_bytes, rcx); | 468 __ Ret(arguments_bytes, rcx); |
| 469 | 469 |
| 470 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 470 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 471 } | 471 } |
| 472 } | 472 } |
| 473 | 473 |
| 474 | 474 |
| 475 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 476 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 477 } |
| 478 |
| 479 |
| 480 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 481 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 482 codegen()->GetVar(result_register(), var); |
| 483 } |
| 484 |
| 485 |
| 475 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 486 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 476 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 487 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 477 MemOperand operand = codegen()->VarOperand(var, result_register()); | 488 MemOperand operand = codegen()->VarOperand(var, result_register()); |
| 478 __ Push(operand); | 489 __ Push(operand); |
| 479 } | 490 } |
| 480 | 491 |
| 481 | 492 |
| 493 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 494 codegen()->GetVar(result_register(), var); |
| 495 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 496 codegen()->DoTest(this); |
| 497 } |
| 498 |
| 499 |
| 482 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 500 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 483 } | 501 } |
| 484 | 502 |
| 485 | 503 |
| 486 void FullCodeGenerator::AccumulatorValueContext::Plug( | 504 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 487 Heap::RootListIndex index) const { | 505 Heap::RootListIndex index) const { |
| 488 __ LoadRoot(result_register(), index); | 506 __ LoadRoot(result_register(), index); |
| 489 } | 507 } |
| 490 | 508 |
| 491 | 509 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 } | 652 } |
| 635 | 653 |
| 636 | 654 |
| 637 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 655 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 638 Label* materialize_false) const { | 656 Label* materialize_false) const { |
| 639 DCHECK(materialize_true == true_label_); | 657 DCHECK(materialize_true == true_label_); |
| 640 DCHECK(materialize_false == false_label_); | 658 DCHECK(materialize_false == false_label_); |
| 641 } | 659 } |
| 642 | 660 |
| 643 | 661 |
| 662 void FullCodeGenerator::EffectContext::Plug(bool flag) const { |
| 663 } |
| 664 |
| 665 |
| 644 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 666 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 645 Heap::RootListIndex value_root_index = | 667 Heap::RootListIndex value_root_index = |
| 646 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 668 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 647 __ LoadRoot(result_register(), value_root_index); | 669 __ LoadRoot(result_register(), value_root_index); |
| 648 } | 670 } |
| 649 | 671 |
| 650 | 672 |
| 651 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 673 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 652 Heap::RootListIndex value_root_index = | 674 Heap::RootListIndex value_root_index = |
| 653 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 675 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 __ Push(variable->name()); | 916 __ Push(variable->name()); |
| 895 __ Push(Smi::FromInt(NONE)); | 917 __ Push(Smi::FromInt(NONE)); |
| 896 VisitForStackValue(declaration->fun()); | 918 VisitForStackValue(declaration->fun()); |
| 897 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 919 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 898 break; | 920 break; |
| 899 } | 921 } |
| 900 } | 922 } |
| 901 } | 923 } |
| 902 | 924 |
| 903 | 925 |
| 926 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 927 VariableProxy* proxy = declaration->proxy(); |
| 928 Variable* variable = proxy->var(); |
| 929 switch (variable->location()) { |
| 930 case VariableLocation::UNALLOCATED: |
| 931 case VariableLocation::GLOBAL: |
| 932 // TODO(rossberg) |
| 933 break; |
| 934 |
| 935 case VariableLocation::CONTEXT: { |
| 936 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 937 EmitDebugCheckDeclarationContext(variable); |
| 938 // TODO(rossberg) |
| 939 break; |
| 940 } |
| 941 |
| 942 case VariableLocation::PARAMETER: |
| 943 case VariableLocation::LOCAL: |
| 944 case VariableLocation::LOOKUP: |
| 945 UNREACHABLE(); |
| 946 } |
| 947 } |
| 948 |
| 949 |
| 950 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 951 // TODO(rossberg) |
| 952 } |
| 953 |
| 954 |
| 904 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 955 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 905 // Call the runtime to declare the globals. | 956 // Call the runtime to declare the globals. |
| 906 __ Push(rsi); // The context is the first argument. | 957 __ Push(rsi); // The context is the first argument. |
| 907 __ Push(pairs); | 958 __ Push(pairs); |
| 908 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 959 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
| 909 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 960 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 910 // Return value is ignored. | 961 // Return value is ignored. |
| 911 } | 962 } |
| 912 | 963 |
| 913 | 964 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 __ Push(info); | 1274 __ Push(info); |
| 1224 __ Push(pretenure | 1275 __ Push(pretenure |
| 1225 ? isolate()->factory()->true_value() | 1276 ? isolate()->factory()->true_value() |
| 1226 : isolate()->factory()->false_value()); | 1277 : isolate()->factory()->false_value()); |
| 1227 __ CallRuntime(Runtime::kNewClosure, 3); | 1278 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1228 } | 1279 } |
| 1229 context()->Plug(rax); | 1280 context()->Plug(rax); |
| 1230 } | 1281 } |
| 1231 | 1282 |
| 1232 | 1283 |
| 1284 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1285 Comment cmnt(masm_, "[ VariableProxy"); |
| 1286 EmitVariableLoad(expr); |
| 1287 } |
| 1288 |
| 1289 |
| 1233 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1290 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1234 int offset, | 1291 int offset, |
| 1235 FeedbackVectorICSlot slot) { | 1292 FeedbackVectorICSlot slot) { |
| 1236 if (NeedsHomeObject(initializer)) { | 1293 if (NeedsHomeObject(initializer)) { |
| 1237 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1294 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1238 __ Move(StoreDescriptor::NameRegister(), | 1295 __ Move(StoreDescriptor::NameRegister(), |
| 1239 isolate()->factory()->home_object_symbol()); | 1296 isolate()->factory()->home_object_symbol()); |
| 1240 __ movp(StoreDescriptor::ValueRegister(), | 1297 __ movp(StoreDescriptor::ValueRegister(), |
| 1241 Operand(rsp, offset * kPointerSize)); | 1298 Operand(rsp, offset * kPointerSize)); |
| 1242 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1299 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| (...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3719 __ bind(&null); | 3776 __ bind(&null); |
| 3720 __ LoadRoot(rax, Heap::kNullValueRootIndex); | 3777 __ LoadRoot(rax, Heap::kNullValueRootIndex); |
| 3721 | 3778 |
| 3722 // All done. | 3779 // All done. |
| 3723 __ bind(&done); | 3780 __ bind(&done); |
| 3724 | 3781 |
| 3725 context()->Plug(rax); | 3782 context()->Plug(rax); |
| 3726 } | 3783 } |
| 3727 | 3784 |
| 3728 | 3785 |
| 3786 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3787 // Load the arguments on the stack and call the stub. |
| 3788 SubStringStub stub(isolate()); |
| 3789 ZoneList<Expression*>* args = expr->arguments(); |
| 3790 DCHECK(args->length() == 3); |
| 3791 VisitForStackValue(args->at(0)); |
| 3792 VisitForStackValue(args->at(1)); |
| 3793 VisitForStackValue(args->at(2)); |
| 3794 __ CallStub(&stub); |
| 3795 context()->Plug(rax); |
| 3796 } |
| 3797 |
| 3798 |
| 3799 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3800 // Load the arguments on the stack and call the stub. |
| 3801 RegExpExecStub stub(isolate()); |
| 3802 ZoneList<Expression*>* args = expr->arguments(); |
| 3803 DCHECK(args->length() == 4); |
| 3804 VisitForStackValue(args->at(0)); |
| 3805 VisitForStackValue(args->at(1)); |
| 3806 VisitForStackValue(args->at(2)); |
| 3807 VisitForStackValue(args->at(3)); |
| 3808 __ CallStub(&stub); |
| 3809 context()->Plug(rax); |
| 3810 } |
| 3811 |
| 3812 |
| 3729 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3813 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3730 ZoneList<Expression*>* args = expr->arguments(); | 3814 ZoneList<Expression*>* args = expr->arguments(); |
| 3731 DCHECK(args->length() == 1); | 3815 DCHECK(args->length() == 1); |
| 3732 | 3816 |
| 3733 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3817 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3734 | 3818 |
| 3735 Label done; | 3819 Label done; |
| 3736 // If the object is a smi return the object. | 3820 // If the object is a smi return the object. |
| 3737 __ JumpIfSmi(rax, &done); | 3821 __ JumpIfSmi(rax, &done); |
| 3738 // If the object is not a value type, return the object. | 3822 // If the object is not a value type, return the object. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3871 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3955 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 3872 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3956 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); |
| 3873 } | 3957 } |
| 3874 | 3958 |
| 3875 __ movw(FieldOperand(string, index, times_2, SeqTwoByteString::kHeaderSize), | 3959 __ movw(FieldOperand(string, index, times_2, SeqTwoByteString::kHeaderSize), |
| 3876 value); | 3960 value); |
| 3877 context()->Plug(rax); | 3961 context()->Plug(rax); |
| 3878 } | 3962 } |
| 3879 | 3963 |
| 3880 | 3964 |
| 3965 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 3966 // Load the arguments on the stack and call the runtime function. |
| 3967 ZoneList<Expression*>* args = expr->arguments(); |
| 3968 DCHECK(args->length() == 2); |
| 3969 VisitForStackValue(args->at(0)); |
| 3970 VisitForStackValue(args->at(1)); |
| 3971 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 3972 __ CallStub(&stub); |
| 3973 context()->Plug(rax); |
| 3974 } |
| 3975 |
| 3976 |
| 3881 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3977 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3882 ZoneList<Expression*>* args = expr->arguments(); | 3978 ZoneList<Expression*>* args = expr->arguments(); |
| 3883 DCHECK(args->length() == 2); | 3979 DCHECK(args->length() == 2); |
| 3884 | 3980 |
| 3885 VisitForStackValue(args->at(0)); // Load the object. | 3981 VisitForStackValue(args->at(0)); // Load the object. |
| 3886 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3982 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 3887 __ Pop(rbx); // rax = value. rbx = object. | 3983 __ Pop(rbx); // rax = value. rbx = object. |
| 3888 | 3984 |
| 3889 Label done; | 3985 Label done; |
| 3890 // If the object is a smi, return the value. | 3986 // If the object is a smi, return the value. |
| 3891 __ JumpIfSmi(rbx, &done); | 3987 __ JumpIfSmi(rbx, &done); |
| 3892 | 3988 |
| 3893 // If the object is not a value type, return the value. | 3989 // If the object is not a value type, return the value. |
| 3894 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); | 3990 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); |
| 3895 __ j(not_equal, &done); | 3991 __ j(not_equal, &done); |
| 3896 | 3992 |
| 3897 // Store the value. | 3993 // Store the value. |
| 3898 __ movp(FieldOperand(rbx, JSValue::kValueOffset), rax); | 3994 __ movp(FieldOperand(rbx, JSValue::kValueOffset), rax); |
| 3899 // Update the write barrier. Save the value as it will be | 3995 // Update the write barrier. Save the value as it will be |
| 3900 // overwritten by the write barrier code and is needed afterward. | 3996 // overwritten by the write barrier code and is needed afterward. |
| 3901 __ movp(rdx, rax); | 3997 __ movp(rdx, rax); |
| 3902 __ RecordWriteField(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs); | 3998 __ RecordWriteField(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs); |
| 3903 | 3999 |
| 3904 __ bind(&done); | 4000 __ bind(&done); |
| 3905 context()->Plug(rax); | 4001 context()->Plug(rax); |
| 3906 } | 4002 } |
| 3907 | 4003 |
| 4004 |
| 4005 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 4006 ZoneList<Expression*>* args = expr->arguments(); |
| 4007 DCHECK_EQ(args->length(), 1); |
| 4008 |
| 4009 // Load the argument into rax and call the stub. |
| 4010 VisitForAccumulatorValue(args->at(0)); |
| 4011 |
| 4012 NumberToStringStub stub(isolate()); |
| 4013 __ CallStub(&stub); |
| 4014 context()->Plug(rax); |
| 4015 } |
| 4016 |
| 3908 | 4017 |
| 3909 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 4018 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 3910 ZoneList<Expression*>* args = expr->arguments(); | 4019 ZoneList<Expression*>* args = expr->arguments(); |
| 3911 DCHECK(args->length() == 1); | 4020 DCHECK(args->length() == 1); |
| 3912 | 4021 |
| 3913 VisitForAccumulatorValue(args->at(0)); | 4022 VisitForAccumulatorValue(args->at(0)); |
| 3914 | 4023 |
| 3915 Label done; | 4024 Label done; |
| 3916 StringCharFromCodeGenerator generator(rax, rbx); | 4025 StringCharFromCodeGenerator generator(rax, rbx); |
| 3917 generator.GenerateFast(masm_); | 4026 generator.GenerateFast(masm_); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4023 ZoneList<Expression*>* args = expr->arguments(); | 4132 ZoneList<Expression*>* args = expr->arguments(); |
| 4024 DCHECK_EQ(2, args->length()); | 4133 DCHECK_EQ(2, args->length()); |
| 4025 VisitForStackValue(args->at(0)); | 4134 VisitForStackValue(args->at(0)); |
| 4026 VisitForAccumulatorValue(args->at(1)); | 4135 VisitForAccumulatorValue(args->at(1)); |
| 4027 | 4136 |
| 4028 __ Pop(rdx); | 4137 __ Pop(rdx); |
| 4029 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4138 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 4030 __ CallStub(&stub); | 4139 __ CallStub(&stub); |
| 4031 context()->Plug(rax); | 4140 context()->Plug(rax); |
| 4032 } | 4141 } |
| 4142 |
| 4143 |
| 4144 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 4145 ZoneList<Expression*>* args = expr->arguments(); |
| 4146 DCHECK_EQ(2, args->length()); |
| 4147 |
| 4148 VisitForStackValue(args->at(0)); |
| 4149 VisitForStackValue(args->at(1)); |
| 4150 |
| 4151 StringCompareStub stub(isolate()); |
| 4152 __ CallStub(&stub); |
| 4153 context()->Plug(rax); |
| 4154 } |
| 4033 | 4155 |
| 4034 | 4156 |
| 4035 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4157 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 4036 ZoneList<Expression*>* args = expr->arguments(); | 4158 ZoneList<Expression*>* args = expr->arguments(); |
| 4037 DCHECK(args->length() >= 2); | 4159 DCHECK(args->length() >= 2); |
| 4038 | 4160 |
| 4039 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4161 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 4040 for (int i = 0; i < arg_count + 1; i++) { | 4162 for (int i = 0; i < arg_count + 1; i++) { |
| 4041 VisitForStackValue(args->at(i)); | 4163 VisitForStackValue(args->at(i)); |
| 4042 } | 4164 } |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5343 Assembler::target_address_at(call_target_address, | 5465 Assembler::target_address_at(call_target_address, |
| 5344 unoptimized_code)); | 5466 unoptimized_code)); |
| 5345 return OSR_AFTER_STACK_CHECK; | 5467 return OSR_AFTER_STACK_CHECK; |
| 5346 } | 5468 } |
| 5347 | 5469 |
| 5348 | 5470 |
| 5349 } // namespace internal | 5471 } // namespace internal |
| 5350 } // namespace v8 | 5472 } // namespace v8 |
| 5351 | 5473 |
| 5352 #endif // V8_TARGET_ARCH_X64 | 5474 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |