| 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_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 __ leave(); | 458 __ leave(); |
| 459 | 459 |
| 460 int arg_count = info_->scope()->num_parameters() + 1; | 460 int arg_count = info_->scope()->num_parameters() + 1; |
| 461 int arguments_bytes = arg_count * kPointerSize; | 461 int arguments_bytes = arg_count * kPointerSize; |
| 462 __ Ret(arguments_bytes, ecx); | 462 __ Ret(arguments_bytes, ecx); |
| 463 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 463 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 464 } | 464 } |
| 465 } | 465 } |
| 466 | 466 |
| 467 | 467 |
| 468 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { | |
| 469 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
| 470 } | |
| 471 | |
| 472 | |
| 473 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { | |
| 474 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
| 475 codegen()->GetVar(result_register(), var); | |
| 476 } | |
| 477 | |
| 478 | |
| 479 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 468 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 480 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 469 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 481 MemOperand operand = codegen()->VarOperand(var, result_register()); | 470 MemOperand operand = codegen()->VarOperand(var, result_register()); |
| 482 // Memory operands can be pushed directly. | 471 // Memory operands can be pushed directly. |
| 483 __ push(operand); | 472 __ push(operand); |
| 484 } | 473 } |
| 485 | 474 |
| 486 | 475 |
| 487 void FullCodeGenerator::TestContext::Plug(Variable* var) const { | |
| 488 // For simplicity we always test the accumulator register. | |
| 489 codegen()->GetVar(result_register(), var); | |
| 490 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
| 491 codegen()->DoTest(this); | |
| 492 } | |
| 493 | |
| 494 | |
| 495 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 476 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 496 UNREACHABLE(); // Not used on X87. | 477 UNREACHABLE(); // Not used on X87. |
| 497 } | 478 } |
| 498 | 479 |
| 499 | 480 |
| 500 void FullCodeGenerator::AccumulatorValueContext::Plug( | 481 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 501 Heap::RootListIndex index) const { | 482 Heap::RootListIndex index) const { |
| 502 UNREACHABLE(); // Not used on X87. | 483 UNREACHABLE(); // Not used on X87. |
| 503 } | 484 } |
| 504 | 485 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 } | 616 } |
| 636 | 617 |
| 637 | 618 |
| 638 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 619 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 639 Label* materialize_false) const { | 620 Label* materialize_false) const { |
| 640 DCHECK(materialize_true == true_label_); | 621 DCHECK(materialize_true == true_label_); |
| 641 DCHECK(materialize_false == false_label_); | 622 DCHECK(materialize_false == false_label_); |
| 642 } | 623 } |
| 643 | 624 |
| 644 | 625 |
| 645 void FullCodeGenerator::EffectContext::Plug(bool flag) const { | |
| 646 } | |
| 647 | |
| 648 | |
| 649 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 626 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 650 Handle<Object> value = flag | 627 Handle<Object> value = flag |
| 651 ? isolate()->factory()->true_value() | 628 ? isolate()->factory()->true_value() |
| 652 : isolate()->factory()->false_value(); | 629 : isolate()->factory()->false_value(); |
| 653 __ mov(result_register(), value); | 630 __ mov(result_register(), value); |
| 654 } | 631 } |
| 655 | 632 |
| 656 | 633 |
| 657 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 634 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 658 Handle<Object> value = flag | 635 Handle<Object> value = flag |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 __ push(Immediate(variable->name())); | 872 __ push(Immediate(variable->name())); |
| 896 __ push(Immediate(Smi::FromInt(NONE))); | 873 __ push(Immediate(Smi::FromInt(NONE))); |
| 897 VisitForStackValue(declaration->fun()); | 874 VisitForStackValue(declaration->fun()); |
| 898 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 875 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 899 break; | 876 break; |
| 900 } | 877 } |
| 901 } | 878 } |
| 902 } | 879 } |
| 903 | 880 |
| 904 | 881 |
| 905 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | |
| 906 VariableProxy* proxy = declaration->proxy(); | |
| 907 Variable* variable = proxy->var(); | |
| 908 switch (variable->location()) { | |
| 909 case VariableLocation::GLOBAL: | |
| 910 case VariableLocation::UNALLOCATED: | |
| 911 // TODO(rossberg) | |
| 912 break; | |
| 913 | |
| 914 case VariableLocation::CONTEXT: { | |
| 915 Comment cmnt(masm_, "[ ImportDeclaration"); | |
| 916 EmitDebugCheckDeclarationContext(variable); | |
| 917 // TODO(rossberg) | |
| 918 break; | |
| 919 } | |
| 920 | |
| 921 case VariableLocation::PARAMETER: | |
| 922 case VariableLocation::LOCAL: | |
| 923 case VariableLocation::LOOKUP: | |
| 924 UNREACHABLE(); | |
| 925 } | |
| 926 } | |
| 927 | |
| 928 | |
| 929 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | |
| 930 // TODO(rossberg) | |
| 931 } | |
| 932 | |
| 933 | |
| 934 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 882 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 935 // Call the runtime to declare the globals. | 883 // Call the runtime to declare the globals. |
| 936 __ push(esi); // The context is the first argument. | 884 __ push(esi); // The context is the first argument. |
| 937 __ Push(pairs); | 885 __ Push(pairs); |
| 938 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 886 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
| 939 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 887 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 940 // Return value is ignored. | 888 // Return value is ignored. |
| 941 } | 889 } |
| 942 | 890 |
| 943 | 891 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 __ push(Immediate(info)); | 1188 __ push(Immediate(info)); |
| 1241 __ push(Immediate(pretenure | 1189 __ push(Immediate(pretenure |
| 1242 ? isolate()->factory()->true_value() | 1190 ? isolate()->factory()->true_value() |
| 1243 : isolate()->factory()->false_value())); | 1191 : isolate()->factory()->false_value())); |
| 1244 __ CallRuntime(Runtime::kNewClosure, 3); | 1192 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1245 } | 1193 } |
| 1246 context()->Plug(eax); | 1194 context()->Plug(eax); |
| 1247 } | 1195 } |
| 1248 | 1196 |
| 1249 | 1197 |
| 1250 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | |
| 1251 Comment cmnt(masm_, "[ VariableProxy"); | |
| 1252 EmitVariableLoad(expr); | |
| 1253 } | |
| 1254 | |
| 1255 | |
| 1256 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1198 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1257 int offset, | 1199 int offset, |
| 1258 FeedbackVectorICSlot slot) { | 1200 FeedbackVectorICSlot slot) { |
| 1259 if (NeedsHomeObject(initializer)) { | 1201 if (NeedsHomeObject(initializer)) { |
| 1260 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1202 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1261 __ mov(StoreDescriptor::NameRegister(), | 1203 __ mov(StoreDescriptor::NameRegister(), |
| 1262 Immediate(isolate()->factory()->home_object_symbol())); | 1204 Immediate(isolate()->factory()->home_object_symbol())); |
| 1263 __ mov(StoreDescriptor::ValueRegister(), | 1205 __ mov(StoreDescriptor::ValueRegister(), |
| 1264 Operand(esp, offset * kPointerSize)); | 1206 Operand(esp, offset * kPointerSize)); |
| 1265 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1207 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| (...skipping 2515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3781 __ bind(&null); | 3723 __ bind(&null); |
| 3782 __ mov(eax, isolate()->factory()->null_value()); | 3724 __ mov(eax, isolate()->factory()->null_value()); |
| 3783 | 3725 |
| 3784 // All done. | 3726 // All done. |
| 3785 __ bind(&done); | 3727 __ bind(&done); |
| 3786 | 3728 |
| 3787 context()->Plug(eax); | 3729 context()->Plug(eax); |
| 3788 } | 3730 } |
| 3789 | 3731 |
| 3790 | 3732 |
| 3791 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | |
| 3792 // Load the arguments on the stack and call the stub. | |
| 3793 SubStringStub stub(isolate()); | |
| 3794 ZoneList<Expression*>* args = expr->arguments(); | |
| 3795 DCHECK(args->length() == 3); | |
| 3796 VisitForStackValue(args->at(0)); | |
| 3797 VisitForStackValue(args->at(1)); | |
| 3798 VisitForStackValue(args->at(2)); | |
| 3799 __ CallStub(&stub); | |
| 3800 context()->Plug(eax); | |
| 3801 } | |
| 3802 | |
| 3803 | |
| 3804 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | |
| 3805 // Load the arguments on the stack and call the stub. | |
| 3806 RegExpExecStub stub(isolate()); | |
| 3807 ZoneList<Expression*>* args = expr->arguments(); | |
| 3808 DCHECK(args->length() == 4); | |
| 3809 VisitForStackValue(args->at(0)); | |
| 3810 VisitForStackValue(args->at(1)); | |
| 3811 VisitForStackValue(args->at(2)); | |
| 3812 VisitForStackValue(args->at(3)); | |
| 3813 __ CallStub(&stub); | |
| 3814 context()->Plug(eax); | |
| 3815 } | |
| 3816 | |
| 3817 | |
| 3818 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3733 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3819 ZoneList<Expression*>* args = expr->arguments(); | 3734 ZoneList<Expression*>* args = expr->arguments(); |
| 3820 DCHECK(args->length() == 1); | 3735 DCHECK(args->length() == 1); |
| 3821 | 3736 |
| 3822 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3737 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3823 | 3738 |
| 3824 Label done; | 3739 Label done; |
| 3825 // If the object is a smi return the object. | 3740 // If the object is a smi return the object. |
| 3826 __ JumpIfSmi(eax, &done, Label::kNear); | 3741 __ JumpIfSmi(eax, &done, Label::kNear); |
| 3827 // If the object is not a value type, return the object. | 3742 // If the object is not a value type, return the object. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3955 } | 3870 } |
| 3956 | 3871 |
| 3957 __ SmiUntag(value); | 3872 __ SmiUntag(value); |
| 3958 // No need to untag a smi for two-byte addressing. | 3873 // No need to untag a smi for two-byte addressing. |
| 3959 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), | 3874 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), |
| 3960 value); | 3875 value); |
| 3961 context()->Plug(string); | 3876 context()->Plug(string); |
| 3962 } | 3877 } |
| 3963 | 3878 |
| 3964 | 3879 |
| 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 | |
| 3972 __ CallRuntime(Runtime::kMathPowSlow, 2); | |
| 3973 context()->Plug(eax); | |
| 3974 } | |
| 3975 | |
| 3976 | |
| 3977 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3880 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3978 ZoneList<Expression*>* args = expr->arguments(); | 3881 ZoneList<Expression*>* args = expr->arguments(); |
| 3979 DCHECK(args->length() == 2); | 3882 DCHECK(args->length() == 2); |
| 3980 | 3883 |
| 3981 VisitForStackValue(args->at(0)); // Load the object. | 3884 VisitForStackValue(args->at(0)); // Load the object. |
| 3982 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3885 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 3983 __ pop(ebx); // eax = value. ebx = object. | 3886 __ pop(ebx); // eax = value. ebx = object. |
| 3984 | 3887 |
| 3985 Label done; | 3888 Label done; |
| 3986 // If the object is a smi, return the value. | 3889 // If the object is a smi, return the value. |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4135 VisitForStackValue(args->at(0)); | 4038 VisitForStackValue(args->at(0)); |
| 4136 VisitForAccumulatorValue(args->at(1)); | 4039 VisitForAccumulatorValue(args->at(1)); |
| 4137 | 4040 |
| 4138 __ pop(edx); | 4041 __ pop(edx); |
| 4139 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4042 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 4140 __ CallStub(&stub); | 4043 __ CallStub(&stub); |
| 4141 context()->Plug(eax); | 4044 context()->Plug(eax); |
| 4142 } | 4045 } |
| 4143 | 4046 |
| 4144 | 4047 |
| 4145 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | |
| 4146 ZoneList<Expression*>* args = expr->arguments(); | |
| 4147 DCHECK_EQ(2, args->length()); | |
| 4148 | |
| 4149 VisitForStackValue(args->at(0)); | |
| 4150 VisitForStackValue(args->at(1)); | |
| 4151 | |
| 4152 StringCompareStub stub(isolate()); | |
| 4153 __ CallStub(&stub); | |
| 4154 context()->Plug(eax); | |
| 4155 } | |
| 4156 | |
| 4157 | |
| 4158 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4048 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 4159 ZoneList<Expression*>* args = expr->arguments(); | 4049 ZoneList<Expression*>* args = expr->arguments(); |
| 4160 DCHECK(args->length() >= 2); | 4050 DCHECK(args->length() >= 2); |
| 4161 | 4051 |
| 4162 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4052 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 4163 for (int i = 0; i < arg_count + 1; ++i) { | 4053 for (int i = 0; i < arg_count + 1; ++i) { |
| 4164 VisitForStackValue(args->at(i)); | 4054 VisitForStackValue(args->at(i)); |
| 4165 } | 4055 } |
| 4166 VisitForAccumulatorValue(args->last()); // Function. | 4056 VisitForAccumulatorValue(args->last()); // Function. |
| 4167 | 4057 |
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5438 Assembler::target_address_at(call_target_address, | 5328 Assembler::target_address_at(call_target_address, |
| 5439 unoptimized_code)); | 5329 unoptimized_code)); |
| 5440 return OSR_AFTER_STACK_CHECK; | 5330 return OSR_AFTER_STACK_CHECK; |
| 5441 } | 5331 } |
| 5442 | 5332 |
| 5443 | 5333 |
| 5444 } // namespace internal | 5334 } // namespace internal |
| 5445 } // namespace v8 | 5335 } // namespace v8 |
| 5446 | 5336 |
| 5447 #endif // V8_TARGET_ARCH_X87 | 5337 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |