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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 int no_frame_start = masm_->pc_offset(); | 497 int no_frame_start = masm_->pc_offset(); |
498 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); | 498 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); |
499 masm_->Addu(sp, sp, Operand(sp_delta)); | 499 masm_->Addu(sp, sp, Operand(sp_delta)); |
500 masm_->Jump(ra); | 500 masm_->Jump(ra); |
501 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 501 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
502 } | 502 } |
503 } | 503 } |
504 } | 504 } |
505 | 505 |
506 | 506 |
| 507 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 508 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 509 } |
| 510 |
| 511 |
| 512 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 513 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 514 codegen()->GetVar(result_register(), var); |
| 515 } |
| 516 |
| 517 |
507 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 518 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
508 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 519 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
509 codegen()->GetVar(result_register(), var); | 520 codegen()->GetVar(result_register(), var); |
510 __ push(result_register()); | 521 __ push(result_register()); |
511 } | 522 } |
512 | 523 |
513 | 524 |
| 525 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 526 // For simplicity we always test the accumulator register. |
| 527 codegen()->GetVar(result_register(), var); |
| 528 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 529 codegen()->DoTest(this); |
| 530 } |
| 531 |
| 532 |
514 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 533 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
515 } | 534 } |
516 | 535 |
517 | 536 |
518 void FullCodeGenerator::AccumulatorValueContext::Plug( | 537 void FullCodeGenerator::AccumulatorValueContext::Plug( |
519 Heap::RootListIndex index) const { | 538 Heap::RootListIndex index) const { |
520 __ LoadRoot(result_register(), index); | 539 __ LoadRoot(result_register(), index); |
521 } | 540 } |
522 | 541 |
523 | 542 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 } | 683 } |
665 | 684 |
666 | 685 |
667 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 686 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
668 Label* materialize_false) const { | 687 Label* materialize_false) const { |
669 DCHECK(materialize_true == true_label_); | 688 DCHECK(materialize_true == true_label_); |
670 DCHECK(materialize_false == false_label_); | 689 DCHECK(materialize_false == false_label_); |
671 } | 690 } |
672 | 691 |
673 | 692 |
| 693 void FullCodeGenerator::EffectContext::Plug(bool flag) const { |
| 694 } |
| 695 |
| 696 |
674 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 697 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
675 Heap::RootListIndex value_root_index = | 698 Heap::RootListIndex value_root_index = |
676 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 699 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
677 __ LoadRoot(result_register(), value_root_index); | 700 __ LoadRoot(result_register(), value_root_index); |
678 } | 701 } |
679 | 702 |
680 | 703 |
681 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 704 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
682 Heap::RootListIndex value_root_index = | 705 Heap::RootListIndex value_root_index = |
683 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 706 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 __ Push(cp, a2, a1); | 959 __ Push(cp, a2, a1); |
937 // Push initial value for function declaration. | 960 // Push initial value for function declaration. |
938 VisitForStackValue(declaration->fun()); | 961 VisitForStackValue(declaration->fun()); |
939 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 962 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
940 break; | 963 break; |
941 } | 964 } |
942 } | 965 } |
943 } | 966 } |
944 | 967 |
945 | 968 |
| 969 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 970 VariableProxy* proxy = declaration->proxy(); |
| 971 Variable* variable = proxy->var(); |
| 972 switch (variable->location()) { |
| 973 case VariableLocation::GLOBAL: |
| 974 case VariableLocation::UNALLOCATED: |
| 975 // TODO(rossberg) |
| 976 break; |
| 977 |
| 978 case VariableLocation::CONTEXT: { |
| 979 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 980 EmitDebugCheckDeclarationContext(variable); |
| 981 // TODO(rossberg) |
| 982 break; |
| 983 } |
| 984 |
| 985 case VariableLocation::PARAMETER: |
| 986 case VariableLocation::LOCAL: |
| 987 case VariableLocation::LOOKUP: |
| 988 UNREACHABLE(); |
| 989 } |
| 990 } |
| 991 |
| 992 |
| 993 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 994 // TODO(rossberg) |
| 995 } |
| 996 |
| 997 |
946 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 998 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
947 // Call the runtime to declare the globals. | 999 // Call the runtime to declare the globals. |
948 // The context is the first argument. | 1000 // The context is the first argument. |
949 __ li(a1, Operand(pairs)); | 1001 __ li(a1, Operand(pairs)); |
950 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 1002 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
951 __ Push(cp, a1, a0); | 1003 __ Push(cp, a1, a0); |
952 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1004 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
953 // Return value is ignored. | 1005 // Return value is ignored. |
954 } | 1006 } |
955 | 1007 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 __ li(a0, Operand(info)); | 1313 __ li(a0, Operand(info)); |
1262 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex | 1314 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex |
1263 : Heap::kFalseValueRootIndex); | 1315 : Heap::kFalseValueRootIndex); |
1264 __ Push(cp, a0, a1); | 1316 __ Push(cp, a0, a1); |
1265 __ CallRuntime(Runtime::kNewClosure, 3); | 1317 __ CallRuntime(Runtime::kNewClosure, 3); |
1266 } | 1318 } |
1267 context()->Plug(v0); | 1319 context()->Plug(v0); |
1268 } | 1320 } |
1269 | 1321 |
1270 | 1322 |
| 1323 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1324 Comment cmnt(masm_, "[ VariableProxy"); |
| 1325 EmitVariableLoad(expr); |
| 1326 } |
| 1327 |
| 1328 |
1271 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1329 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
1272 int offset, | 1330 int offset, |
1273 FeedbackVectorICSlot slot) { | 1331 FeedbackVectorICSlot slot) { |
1274 if (NeedsHomeObject(initializer)) { | 1332 if (NeedsHomeObject(initializer)) { |
1275 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1333 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1276 __ li(StoreDescriptor::NameRegister(), | 1334 __ li(StoreDescriptor::NameRegister(), |
1277 Operand(isolate()->factory()->home_object_symbol())); | 1335 Operand(isolate()->factory()->home_object_symbol())); |
1278 __ lw(StoreDescriptor::ValueRegister(), | 1336 __ lw(StoreDescriptor::ValueRegister(), |
1279 MemOperand(sp, offset * kPointerSize)); | 1337 MemOperand(sp, offset * kPointerSize)); |
1280 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1338 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
(...skipping 2547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3828 __ bind(&null); | 3886 __ bind(&null); |
3829 __ LoadRoot(v0, Heap::kNullValueRootIndex); | 3887 __ LoadRoot(v0, Heap::kNullValueRootIndex); |
3830 | 3888 |
3831 // All done. | 3889 // All done. |
3832 __ bind(&done); | 3890 __ bind(&done); |
3833 | 3891 |
3834 context()->Plug(v0); | 3892 context()->Plug(v0); |
3835 } | 3893 } |
3836 | 3894 |
3837 | 3895 |
| 3896 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3897 // Load the arguments on the stack and call the stub. |
| 3898 SubStringStub stub(isolate()); |
| 3899 ZoneList<Expression*>* args = expr->arguments(); |
| 3900 DCHECK(args->length() == 3); |
| 3901 VisitForStackValue(args->at(0)); |
| 3902 VisitForStackValue(args->at(1)); |
| 3903 VisitForStackValue(args->at(2)); |
| 3904 __ CallStub(&stub); |
| 3905 context()->Plug(v0); |
| 3906 } |
| 3907 |
| 3908 |
| 3909 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3910 // Load the arguments on the stack and call the stub. |
| 3911 RegExpExecStub stub(isolate()); |
| 3912 ZoneList<Expression*>* args = expr->arguments(); |
| 3913 DCHECK(args->length() == 4); |
| 3914 VisitForStackValue(args->at(0)); |
| 3915 VisitForStackValue(args->at(1)); |
| 3916 VisitForStackValue(args->at(2)); |
| 3917 VisitForStackValue(args->at(3)); |
| 3918 __ CallStub(&stub); |
| 3919 context()->Plug(v0); |
| 3920 } |
| 3921 |
| 3922 |
3838 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3923 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
3839 ZoneList<Expression*>* args = expr->arguments(); | 3924 ZoneList<Expression*>* args = expr->arguments(); |
3840 DCHECK(args->length() == 1); | 3925 DCHECK(args->length() == 1); |
3841 | 3926 |
3842 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3927 VisitForAccumulatorValue(args->at(0)); // Load the object. |
3843 | 3928 |
3844 Label done; | 3929 Label done; |
3845 // If the object is a smi return the object. | 3930 // If the object is a smi return the object. |
3846 __ JumpIfSmi(v0, &done); | 3931 __ JumpIfSmi(v0, &done); |
3847 // If the object is not a value type, return the object. | 3932 // If the object is not a value type, return the object. |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3983 __ Addu(at, | 4068 __ Addu(at, |
3984 string, | 4069 string, |
3985 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 4070 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
3986 __ Addu(at, at, index); | 4071 __ Addu(at, at, index); |
3987 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 4072 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
3988 __ sh(value, MemOperand(at)); | 4073 __ sh(value, MemOperand(at)); |
3989 context()->Plug(string); | 4074 context()->Plug(string); |
3990 } | 4075 } |
3991 | 4076 |
3992 | 4077 |
| 4078 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 4079 // Load the arguments on the stack and call the runtime function. |
| 4080 ZoneList<Expression*>* args = expr->arguments(); |
| 4081 DCHECK(args->length() == 2); |
| 4082 VisitForStackValue(args->at(0)); |
| 4083 VisitForStackValue(args->at(1)); |
| 4084 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 4085 __ CallStub(&stub); |
| 4086 context()->Plug(v0); |
| 4087 } |
| 4088 |
| 4089 |
3993 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 4090 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
3994 ZoneList<Expression*>* args = expr->arguments(); | 4091 ZoneList<Expression*>* args = expr->arguments(); |
3995 DCHECK(args->length() == 2); | 4092 DCHECK(args->length() == 2); |
3996 | 4093 |
3997 VisitForStackValue(args->at(0)); // Load the object. | 4094 VisitForStackValue(args->at(0)); // Load the object. |
3998 VisitForAccumulatorValue(args->at(1)); // Load the value. | 4095 VisitForAccumulatorValue(args->at(1)); // Load the value. |
3999 __ pop(a1); // v0 = value. a1 = object. | 4096 __ pop(a1); // v0 = value. a1 = object. |
4000 | 4097 |
4001 Label done; | 4098 Label done; |
4002 // If the object is a smi, return the value. | 4099 // If the object is a smi, return the value. |
4003 __ JumpIfSmi(a1, &done); | 4100 __ JumpIfSmi(a1, &done); |
4004 | 4101 |
4005 // If the object is not a value type, return the value. | 4102 // If the object is not a value type, return the value. |
4006 __ GetObjectType(a1, a2, a2); | 4103 __ GetObjectType(a1, a2, a2); |
4007 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); | 4104 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); |
4008 | 4105 |
4009 // Store the value. | 4106 // Store the value. |
4010 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset)); | 4107 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset)); |
4011 // Update the write barrier. Save the value as it will be | 4108 // Update the write barrier. Save the value as it will be |
4012 // overwritten by the write barrier code and is needed afterward. | 4109 // overwritten by the write barrier code and is needed afterward. |
4013 __ mov(a2, v0); | 4110 __ mov(a2, v0); |
4014 __ RecordWriteField( | 4111 __ RecordWriteField( |
4015 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 4112 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
4016 | 4113 |
4017 __ bind(&done); | 4114 __ bind(&done); |
4018 context()->Plug(v0); | 4115 context()->Plug(v0); |
4019 } | 4116 } |
4020 | 4117 |
| 4118 |
| 4119 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 4120 ZoneList<Expression*>* args = expr->arguments(); |
| 4121 DCHECK_EQ(args->length(), 1); |
| 4122 |
| 4123 // Load the argument into a0 and call the stub. |
| 4124 VisitForAccumulatorValue(args->at(0)); |
| 4125 __ mov(a0, result_register()); |
| 4126 |
| 4127 NumberToStringStub stub(isolate()); |
| 4128 __ CallStub(&stub); |
| 4129 context()->Plug(v0); |
| 4130 } |
| 4131 |
4021 | 4132 |
4022 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 4133 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
4023 ZoneList<Expression*>* args = expr->arguments(); | 4134 ZoneList<Expression*>* args = expr->arguments(); |
4024 DCHECK(args->length() == 1); | 4135 DCHECK(args->length() == 1); |
4025 | 4136 |
4026 VisitForAccumulatorValue(args->at(0)); | 4137 VisitForAccumulatorValue(args->at(0)); |
4027 | 4138 |
4028 Label done; | 4139 Label done; |
4029 StringCharFromCodeGenerator generator(v0, a1); | 4140 StringCharFromCodeGenerator generator(v0, a1); |
4030 generator.GenerateFast(masm_); | 4141 generator.GenerateFast(masm_); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4139 DCHECK_EQ(2, args->length()); | 4250 DCHECK_EQ(2, args->length()); |
4140 VisitForStackValue(args->at(0)); | 4251 VisitForStackValue(args->at(0)); |
4141 VisitForAccumulatorValue(args->at(1)); | 4252 VisitForAccumulatorValue(args->at(1)); |
4142 | 4253 |
4143 __ pop(a1); | 4254 __ pop(a1); |
4144 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. | 4255 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. |
4145 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4256 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
4146 __ CallStub(&stub); | 4257 __ CallStub(&stub); |
4147 context()->Plug(v0); | 4258 context()->Plug(v0); |
4148 } | 4259 } |
| 4260 |
| 4261 |
| 4262 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 4263 ZoneList<Expression*>* args = expr->arguments(); |
| 4264 DCHECK_EQ(2, args->length()); |
| 4265 |
| 4266 VisitForStackValue(args->at(0)); |
| 4267 VisitForStackValue(args->at(1)); |
| 4268 |
| 4269 StringCompareStub stub(isolate()); |
| 4270 __ CallStub(&stub); |
| 4271 context()->Plug(v0); |
| 4272 } |
4149 | 4273 |
4150 | 4274 |
4151 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4275 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
4152 ZoneList<Expression*>* args = expr->arguments(); | 4276 ZoneList<Expression*>* args = expr->arguments(); |
4153 DCHECK(args->length() >= 2); | 4277 DCHECK(args->length() >= 2); |
4154 | 4278 |
4155 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4279 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
4156 for (int i = 0; i < arg_count + 1; i++) { | 4280 for (int i = 0; i < arg_count + 1; i++) { |
4157 VisitForStackValue(args->at(i)); | 4281 VisitForStackValue(args->at(i)); |
4158 } | 4282 } |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5412 reinterpret_cast<uint32_t>( | 5536 reinterpret_cast<uint32_t>( |
5413 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5537 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5414 return OSR_AFTER_STACK_CHECK; | 5538 return OSR_AFTER_STACK_CHECK; |
5415 } | 5539 } |
5416 | 5540 |
5417 | 5541 |
5418 } // namespace internal | 5542 } // namespace internal |
5419 } // namespace v8 | 5543 } // namespace v8 |
5420 | 5544 |
5421 #endif // V8_TARGET_ARCH_MIPS | 5545 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |