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 |