| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 __ leave(); | 461 __ leave(); |
| 462 | 462 |
| 463 int arg_count = info_->scope()->num_parameters() + 1; | 463 int arg_count = info_->scope()->num_parameters() + 1; |
| 464 int arguments_bytes = arg_count * kPointerSize; | 464 int arguments_bytes = arg_count * kPointerSize; |
| 465 __ Ret(arguments_bytes, ecx); | 465 __ Ret(arguments_bytes, ecx); |
| 466 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 466 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 | 469 |
| 470 | 470 |
| 471 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { | |
| 472 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
| 473 } | |
| 474 | |
| 475 | |
| 476 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { | |
| 477 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
| 478 codegen()->GetVar(result_register(), var); | |
| 479 } | |
| 480 | |
| 481 | |
| 482 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 471 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 483 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 472 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 484 MemOperand operand = codegen()->VarOperand(var, result_register()); | 473 MemOperand operand = codegen()->VarOperand(var, result_register()); |
| 485 // Memory operands can be pushed directly. | 474 // Memory operands can be pushed directly. |
| 486 __ push(operand); | 475 __ push(operand); |
| 487 } | 476 } |
| 488 | 477 |
| 489 | 478 |
| 490 void FullCodeGenerator::TestContext::Plug(Variable* var) const { | |
| 491 // For simplicity we always test the accumulator register. | |
| 492 codegen()->GetVar(result_register(), var); | |
| 493 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
| 494 codegen()->DoTest(this); | |
| 495 } | |
| 496 | |
| 497 | |
| 498 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 479 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 499 UNREACHABLE(); // Not used on IA32. | 480 UNREACHABLE(); // Not used on IA32. |
| 500 } | 481 } |
| 501 | 482 |
| 502 | 483 |
| 503 void FullCodeGenerator::AccumulatorValueContext::Plug( | 484 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 504 Heap::RootListIndex index) const { | 485 Heap::RootListIndex index) const { |
| 505 UNREACHABLE(); // Not used on IA32. | 486 UNREACHABLE(); // Not used on IA32. |
| 506 } | 487 } |
| 507 | 488 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 } | 619 } |
| 639 | 620 |
| 640 | 621 |
| 641 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 622 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 642 Label* materialize_false) const { | 623 Label* materialize_false) const { |
| 643 DCHECK(materialize_true == true_label_); | 624 DCHECK(materialize_true == true_label_); |
| 644 DCHECK(materialize_false == false_label_); | 625 DCHECK(materialize_false == false_label_); |
| 645 } | 626 } |
| 646 | 627 |
| 647 | 628 |
| 648 void FullCodeGenerator::EffectContext::Plug(bool flag) const { | |
| 649 } | |
| 650 | |
| 651 | |
| 652 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 629 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 653 Handle<Object> value = flag | 630 Handle<Object> value = flag |
| 654 ? isolate()->factory()->true_value() | 631 ? isolate()->factory()->true_value() |
| 655 : isolate()->factory()->false_value(); | 632 : isolate()->factory()->false_value(); |
| 656 __ mov(result_register(), value); | 633 __ mov(result_register(), value); |
| 657 } | 634 } |
| 658 | 635 |
| 659 | 636 |
| 660 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 637 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 661 Handle<Object> value = flag | 638 Handle<Object> value = flag |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 __ push(Immediate(variable->name())); | 879 __ push(Immediate(variable->name())); |
| 903 __ push(Immediate(Smi::FromInt(NONE))); | 880 __ push(Immediate(Smi::FromInt(NONE))); |
| 904 VisitForStackValue(declaration->fun()); | 881 VisitForStackValue(declaration->fun()); |
| 905 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 882 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 906 break; | 883 break; |
| 907 } | 884 } |
| 908 } | 885 } |
| 909 } | 886 } |
| 910 | 887 |
| 911 | 888 |
| 912 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | |
| 913 VariableProxy* proxy = declaration->proxy(); | |
| 914 Variable* variable = proxy->var(); | |
| 915 switch (variable->location()) { | |
| 916 case VariableLocation::GLOBAL: | |
| 917 case VariableLocation::UNALLOCATED: | |
| 918 // TODO(rossberg) | |
| 919 break; | |
| 920 | |
| 921 case VariableLocation::CONTEXT: { | |
| 922 Comment cmnt(masm_, "[ ImportDeclaration"); | |
| 923 EmitDebugCheckDeclarationContext(variable); | |
| 924 // TODO(rossberg) | |
| 925 break; | |
| 926 } | |
| 927 | |
| 928 case VariableLocation::PARAMETER: | |
| 929 case VariableLocation::LOCAL: | |
| 930 case VariableLocation::LOOKUP: | |
| 931 UNREACHABLE(); | |
| 932 } | |
| 933 } | |
| 934 | |
| 935 | |
| 936 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | |
| 937 // TODO(rossberg) | |
| 938 } | |
| 939 | |
| 940 | |
| 941 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 889 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 942 // Call the runtime to declare the globals. | 890 // Call the runtime to declare the globals. |
| 943 __ push(esi); // The context is the first argument. | 891 __ push(esi); // The context is the first argument. |
| 944 __ Push(pairs); | 892 __ Push(pairs); |
| 945 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 893 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
| 946 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 894 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 947 // Return value is ignored. | 895 // Return value is ignored. |
| 948 } | 896 } |
| 949 | 897 |
| 950 | 898 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 __ push(Immediate(info)); | 1195 __ push(Immediate(info)); |
| 1248 __ push(Immediate(pretenure | 1196 __ push(Immediate(pretenure |
| 1249 ? isolate()->factory()->true_value() | 1197 ? isolate()->factory()->true_value() |
| 1250 : isolate()->factory()->false_value())); | 1198 : isolate()->factory()->false_value())); |
| 1251 __ CallRuntime(Runtime::kNewClosure, 3); | 1199 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1252 } | 1200 } |
| 1253 context()->Plug(eax); | 1201 context()->Plug(eax); |
| 1254 } | 1202 } |
| 1255 | 1203 |
| 1256 | 1204 |
| 1257 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | |
| 1258 Comment cmnt(masm_, "[ VariableProxy"); | |
| 1259 EmitVariableLoad(expr); | |
| 1260 } | |
| 1261 | |
| 1262 | |
| 1263 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1205 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1264 int offset, | 1206 int offset, |
| 1265 FeedbackVectorICSlot slot) { | 1207 FeedbackVectorICSlot slot) { |
| 1266 if (NeedsHomeObject(initializer)) { | 1208 if (NeedsHomeObject(initializer)) { |
| 1267 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1209 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1268 __ mov(StoreDescriptor::NameRegister(), | 1210 __ mov(StoreDescriptor::NameRegister(), |
| 1269 Immediate(isolate()->factory()->home_object_symbol())); | 1211 Immediate(isolate()->factory()->home_object_symbol())); |
| 1270 __ mov(StoreDescriptor::ValueRegister(), | 1212 __ mov(StoreDescriptor::ValueRegister(), |
| 1271 Operand(esp, offset * kPointerSize)); | 1213 Operand(esp, offset * kPointerSize)); |
| 1272 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1214 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| (...skipping 2517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3790 __ bind(&null); | 3732 __ bind(&null); |
| 3791 __ mov(eax, isolate()->factory()->null_value()); | 3733 __ mov(eax, isolate()->factory()->null_value()); |
| 3792 | 3734 |
| 3793 // All done. | 3735 // All done. |
| 3794 __ bind(&done); | 3736 __ bind(&done); |
| 3795 | 3737 |
| 3796 context()->Plug(eax); | 3738 context()->Plug(eax); |
| 3797 } | 3739 } |
| 3798 | 3740 |
| 3799 | 3741 |
| 3800 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | |
| 3801 // Load the arguments on the stack and call the stub. | |
| 3802 SubStringStub stub(isolate()); | |
| 3803 ZoneList<Expression*>* args = expr->arguments(); | |
| 3804 DCHECK(args->length() == 3); | |
| 3805 VisitForStackValue(args->at(0)); | |
| 3806 VisitForStackValue(args->at(1)); | |
| 3807 VisitForStackValue(args->at(2)); | |
| 3808 __ CallStub(&stub); | |
| 3809 context()->Plug(eax); | |
| 3810 } | |
| 3811 | |
| 3812 | |
| 3813 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | |
| 3814 // Load the arguments on the stack and call the stub. | |
| 3815 RegExpExecStub stub(isolate()); | |
| 3816 ZoneList<Expression*>* args = expr->arguments(); | |
| 3817 DCHECK(args->length() == 4); | |
| 3818 VisitForStackValue(args->at(0)); | |
| 3819 VisitForStackValue(args->at(1)); | |
| 3820 VisitForStackValue(args->at(2)); | |
| 3821 VisitForStackValue(args->at(3)); | |
| 3822 __ CallStub(&stub); | |
| 3823 context()->Plug(eax); | |
| 3824 } | |
| 3825 | |
| 3826 | |
| 3827 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3742 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3828 ZoneList<Expression*>* args = expr->arguments(); | 3743 ZoneList<Expression*>* args = expr->arguments(); |
| 3829 DCHECK(args->length() == 1); | 3744 DCHECK(args->length() == 1); |
| 3830 | 3745 |
| 3831 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3746 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3832 | 3747 |
| 3833 Label done; | 3748 Label done; |
| 3834 // If the object is a smi return the object. | 3749 // If the object is a smi return the object. |
| 3835 __ JumpIfSmi(eax, &done, Label::kNear); | 3750 __ JumpIfSmi(eax, &done, Label::kNear); |
| 3836 // If the object is not a value type, return the object. | 3751 // If the object is not a value type, return the object. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3964 } | 3879 } |
| 3965 | 3880 |
| 3966 __ SmiUntag(value); | 3881 __ SmiUntag(value); |
| 3967 // No need to untag a smi for two-byte addressing. | 3882 // No need to untag a smi for two-byte addressing. |
| 3968 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), | 3883 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), |
| 3969 value); | 3884 value); |
| 3970 context()->Plug(string); | 3885 context()->Plug(string); |
| 3971 } | 3886 } |
| 3972 | 3887 |
| 3973 | 3888 |
| 3974 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | |
| 3975 // Load the arguments on the stack and call the runtime function. | |
| 3976 ZoneList<Expression*>* args = expr->arguments(); | |
| 3977 DCHECK(args->length() == 2); | |
| 3978 VisitForStackValue(args->at(0)); | |
| 3979 VisitForStackValue(args->at(1)); | |
| 3980 | |
| 3981 MathPowStub stub(isolate(), MathPowStub::ON_STACK); | |
| 3982 __ CallStub(&stub); | |
| 3983 context()->Plug(eax); | |
| 3984 } | |
| 3985 | |
| 3986 | |
| 3987 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3889 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3988 ZoneList<Expression*>* args = expr->arguments(); | 3890 ZoneList<Expression*>* args = expr->arguments(); |
| 3989 DCHECK(args->length() == 2); | 3891 DCHECK(args->length() == 2); |
| 3990 | 3892 |
| 3991 VisitForStackValue(args->at(0)); // Load the object. | 3893 VisitForStackValue(args->at(0)); // Load the object. |
| 3992 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3894 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 3993 __ pop(ebx); // eax = value. ebx = object. | 3895 __ pop(ebx); // eax = value. ebx = object. |
| 3994 | 3896 |
| 3995 Label done; | 3897 Label done; |
| 3996 // If the object is a smi, return the value. | 3898 // If the object is a smi, return the value. |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4145 VisitForStackValue(args->at(0)); | 4047 VisitForStackValue(args->at(0)); |
| 4146 VisitForAccumulatorValue(args->at(1)); | 4048 VisitForAccumulatorValue(args->at(1)); |
| 4147 | 4049 |
| 4148 __ pop(edx); | 4050 __ pop(edx); |
| 4149 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4051 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 4150 __ CallStub(&stub); | 4052 __ CallStub(&stub); |
| 4151 context()->Plug(eax); | 4053 context()->Plug(eax); |
| 4152 } | 4054 } |
| 4153 | 4055 |
| 4154 | 4056 |
| 4155 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | |
| 4156 ZoneList<Expression*>* args = expr->arguments(); | |
| 4157 DCHECK_EQ(2, args->length()); | |
| 4158 | |
| 4159 VisitForStackValue(args->at(0)); | |
| 4160 VisitForStackValue(args->at(1)); | |
| 4161 | |
| 4162 StringCompareStub stub(isolate()); | |
| 4163 __ CallStub(&stub); | |
| 4164 context()->Plug(eax); | |
| 4165 } | |
| 4166 | |
| 4167 | |
| 4168 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4057 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 4169 ZoneList<Expression*>* args = expr->arguments(); | 4058 ZoneList<Expression*>* args = expr->arguments(); |
| 4170 DCHECK(args->length() >= 2); | 4059 DCHECK(args->length() >= 2); |
| 4171 | 4060 |
| 4172 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4061 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 4173 for (int i = 0; i < arg_count + 1; ++i) { | 4062 for (int i = 0; i < arg_count + 1; ++i) { |
| 4174 VisitForStackValue(args->at(i)); | 4063 VisitForStackValue(args->at(i)); |
| 4175 } | 4064 } |
| 4176 VisitForAccumulatorValue(args->last()); // Function. | 4065 VisitForAccumulatorValue(args->last()); // Function. |
| 4177 | 4066 |
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5448 Assembler::target_address_at(call_target_address, | 5337 Assembler::target_address_at(call_target_address, |
| 5449 unoptimized_code)); | 5338 unoptimized_code)); |
| 5450 return OSR_AFTER_STACK_CHECK; | 5339 return OSR_AFTER_STACK_CHECK; |
| 5451 } | 5340 } |
| 5452 | 5341 |
| 5453 | 5342 |
| 5454 } // namespace internal | 5343 } // namespace internal |
| 5455 } // namespace v8 | 5344 } // namespace v8 |
| 5456 | 5345 |
| 5457 #endif // V8_TARGET_ARCH_IA32 | 5346 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |