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 |