| 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 | 
|---|