| 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | 502 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); |
| 503 __ add(sp, sp, Operand(sp_delta)); | 503 __ add(sp, sp, Operand(sp_delta)); |
| 504 __ Jump(lr); | 504 __ Jump(lr); |
| 505 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 505 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 | 510 |
| 511 | 511 |
| 512 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 513 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 514 } |
| 515 |
| 516 |
| 517 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 518 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 519 codegen()->GetVar(result_register(), var); |
| 520 } |
| 521 |
| 522 |
| 512 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 523 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 513 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 524 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 514 codegen()->GetVar(result_register(), var); | 525 codegen()->GetVar(result_register(), var); |
| 515 __ push(result_register()); | 526 __ push(result_register()); |
| 516 } | 527 } |
| 517 | 528 |
| 518 | 529 |
| 530 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 531 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 532 // For simplicity we always test the accumulator register. |
| 533 codegen()->GetVar(result_register(), var); |
| 534 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 535 codegen()->DoTest(this); |
| 536 } |
| 537 |
| 538 |
| 519 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 539 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 520 } | 540 } |
| 521 | 541 |
| 522 | 542 |
| 523 void FullCodeGenerator::AccumulatorValueContext::Plug( | 543 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 524 Heap::RootListIndex index) const { | 544 Heap::RootListIndex index) const { |
| 525 __ LoadRoot(result_register(), index); | 545 __ LoadRoot(result_register(), index); |
| 526 } | 546 } |
| 527 | 547 |
| 528 | 548 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 } | 687 } |
| 668 | 688 |
| 669 | 689 |
| 670 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 690 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 671 Label* materialize_false) const { | 691 Label* materialize_false) const { |
| 672 DCHECK(materialize_true == true_label_); | 692 DCHECK(materialize_true == true_label_); |
| 673 DCHECK(materialize_false == false_label_); | 693 DCHECK(materialize_false == false_label_); |
| 674 } | 694 } |
| 675 | 695 |
| 676 | 696 |
| 697 void FullCodeGenerator::EffectContext::Plug(bool flag) const { |
| 698 } |
| 699 |
| 700 |
| 677 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 701 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 678 Heap::RootListIndex value_root_index = | 702 Heap::RootListIndex value_root_index = |
| 679 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 703 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 680 __ LoadRoot(result_register(), value_root_index); | 704 __ LoadRoot(result_register(), value_root_index); |
| 681 } | 705 } |
| 682 | 706 |
| 683 | 707 |
| 684 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 708 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 685 Heap::RootListIndex value_root_index = | 709 Heap::RootListIndex value_root_index = |
| 686 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 710 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 __ Push(cp, r2, r1); | 959 __ Push(cp, r2, r1); |
| 936 // Push initial value for function declaration. | 960 // Push initial value for function declaration. |
| 937 VisitForStackValue(declaration->fun()); | 961 VisitForStackValue(declaration->fun()); |
| 938 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 962 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 939 break; | 963 break; |
| 940 } | 964 } |
| 941 } | 965 } |
| 942 } | 966 } |
| 943 | 967 |
| 944 | 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 |
| 945 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 998 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 946 // Call the runtime to declare the globals. | 999 // Call the runtime to declare the globals. |
| 947 // The context is the first argument. | 1000 // The context is the first argument. |
| 948 __ mov(r1, Operand(pairs)); | 1001 __ mov(r1, Operand(pairs)); |
| 949 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 1002 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
| 950 __ Push(cp, r1, r0); | 1003 __ Push(cp, r1, r0); |
| 951 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1004 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 952 // Return value is ignored. | 1005 // Return value is ignored. |
| 953 } | 1006 } |
| 954 | 1007 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 __ mov(r0, Operand(info)); | 1319 __ mov(r0, Operand(info)); |
| 1267 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1320 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
| 1268 : Heap::kFalseValueRootIndex); | 1321 : Heap::kFalseValueRootIndex); |
| 1269 __ Push(cp, r0, r1); | 1322 __ Push(cp, r0, r1); |
| 1270 __ CallRuntime(Runtime::kNewClosure, 3); | 1323 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1271 } | 1324 } |
| 1272 context()->Plug(r0); | 1325 context()->Plug(r0); |
| 1273 } | 1326 } |
| 1274 | 1327 |
| 1275 | 1328 |
| 1329 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1330 Comment cmnt(masm_, "[ VariableProxy"); |
| 1331 EmitVariableLoad(expr); |
| 1332 } |
| 1333 |
| 1334 |
| 1276 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1335 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1277 int offset, | 1336 int offset, |
| 1278 FeedbackVectorICSlot slot) { | 1337 FeedbackVectorICSlot slot) { |
| 1279 if (NeedsHomeObject(initializer)) { | 1338 if (NeedsHomeObject(initializer)) { |
| 1280 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1339 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1281 __ mov(StoreDescriptor::NameRegister(), | 1340 __ mov(StoreDescriptor::NameRegister(), |
| 1282 Operand(isolate()->factory()->home_object_symbol())); | 1341 Operand(isolate()->factory()->home_object_symbol())); |
| 1283 __ ldr(StoreDescriptor::ValueRegister(), | 1342 __ ldr(StoreDescriptor::ValueRegister(), |
| 1284 MemOperand(sp, offset * kPointerSize)); | 1343 MemOperand(sp, offset * kPointerSize)); |
| 1285 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1344 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| (...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3840 __ bind(&null); | 3899 __ bind(&null); |
| 3841 __ LoadRoot(r0, Heap::kNullValueRootIndex); | 3900 __ LoadRoot(r0, Heap::kNullValueRootIndex); |
| 3842 | 3901 |
| 3843 // All done. | 3902 // All done. |
| 3844 __ bind(&done); | 3903 __ bind(&done); |
| 3845 | 3904 |
| 3846 context()->Plug(r0); | 3905 context()->Plug(r0); |
| 3847 } | 3906 } |
| 3848 | 3907 |
| 3849 | 3908 |
| 3909 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3910 // Load the arguments on the stack and call the stub. |
| 3911 SubStringStub stub(isolate()); |
| 3912 ZoneList<Expression*>* args = expr->arguments(); |
| 3913 DCHECK(args->length() == 3); |
| 3914 VisitForStackValue(args->at(0)); |
| 3915 VisitForStackValue(args->at(1)); |
| 3916 VisitForStackValue(args->at(2)); |
| 3917 __ CallStub(&stub); |
| 3918 context()->Plug(r0); |
| 3919 } |
| 3920 |
| 3921 |
| 3922 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3923 // Load the arguments on the stack and call the stub. |
| 3924 RegExpExecStub stub(isolate()); |
| 3925 ZoneList<Expression*>* args = expr->arguments(); |
| 3926 DCHECK(args->length() == 4); |
| 3927 VisitForStackValue(args->at(0)); |
| 3928 VisitForStackValue(args->at(1)); |
| 3929 VisitForStackValue(args->at(2)); |
| 3930 VisitForStackValue(args->at(3)); |
| 3931 __ CallStub(&stub); |
| 3932 context()->Plug(r0); |
| 3933 } |
| 3934 |
| 3935 |
| 3850 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3936 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3851 ZoneList<Expression*>* args = expr->arguments(); | 3937 ZoneList<Expression*>* args = expr->arguments(); |
| 3852 DCHECK(args->length() == 1); | 3938 DCHECK(args->length() == 1); |
| 3853 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3939 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3854 | 3940 |
| 3855 Label done; | 3941 Label done; |
| 3856 // If the object is a smi return the object. | 3942 // If the object is a smi return the object. |
| 3857 __ JumpIfSmi(r0, &done); | 3943 __ JumpIfSmi(r0, &done); |
| 3858 // If the object is not a value type, return the object. | 3944 // If the object is not a value type, return the object. |
| 3859 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); | 3945 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3985 __ SmiUntag(value, value); | 4071 __ SmiUntag(value, value); |
| 3986 __ add(ip, | 4072 __ add(ip, |
| 3987 string, | 4073 string, |
| 3988 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 4074 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 3989 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 4075 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 3990 __ strh(value, MemOperand(ip, index)); | 4076 __ strh(value, MemOperand(ip, index)); |
| 3991 context()->Plug(string); | 4077 context()->Plug(string); |
| 3992 } | 4078 } |
| 3993 | 4079 |
| 3994 | 4080 |
| 4081 |
| 4082 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 4083 // Load the arguments on the stack and call the runtime function. |
| 4084 ZoneList<Expression*>* args = expr->arguments(); |
| 4085 DCHECK(args->length() == 2); |
| 4086 VisitForStackValue(args->at(0)); |
| 4087 VisitForStackValue(args->at(1)); |
| 4088 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 4089 __ CallStub(&stub); |
| 4090 context()->Plug(r0); |
| 4091 } |
| 4092 |
| 4093 |
| 3995 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 4094 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3996 ZoneList<Expression*>* args = expr->arguments(); | 4095 ZoneList<Expression*>* args = expr->arguments(); |
| 3997 DCHECK(args->length() == 2); | 4096 DCHECK(args->length() == 2); |
| 3998 VisitForStackValue(args->at(0)); // Load the object. | 4097 VisitForStackValue(args->at(0)); // Load the object. |
| 3999 VisitForAccumulatorValue(args->at(1)); // Load the value. | 4098 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 4000 __ pop(r1); // r0 = value. r1 = object. | 4099 __ pop(r1); // r0 = value. r1 = object. |
| 4001 | 4100 |
| 4002 Label done; | 4101 Label done; |
| 4003 // If the object is a smi, return the value. | 4102 // If the object is a smi, return the value. |
| 4004 __ JumpIfSmi(r1, &done); | 4103 __ JumpIfSmi(r1, &done); |
| 4005 | 4104 |
| 4006 // If the object is not a value type, return the value. | 4105 // If the object is not a value type, return the value. |
| 4007 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); | 4106 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); |
| 4008 __ b(ne, &done); | 4107 __ b(ne, &done); |
| 4009 | 4108 |
| 4010 // Store the value. | 4109 // Store the value. |
| 4011 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); | 4110 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); |
| 4012 // Update the write barrier. Save the value as it will be | 4111 // Update the write barrier. Save the value as it will be |
| 4013 // overwritten by the write barrier code and is needed afterward. | 4112 // overwritten by the write barrier code and is needed afterward. |
| 4014 __ mov(r2, r0); | 4113 __ mov(r2, r0); |
| 4015 __ RecordWriteField( | 4114 __ RecordWriteField( |
| 4016 r1, JSValue::kValueOffset, r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 4115 r1, JSValue::kValueOffset, r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
| 4017 | 4116 |
| 4018 __ bind(&done); | 4117 __ bind(&done); |
| 4019 context()->Plug(r0); | 4118 context()->Plug(r0); |
| 4020 } | 4119 } |
| 4021 | 4120 |
| 4121 |
| 4122 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 4123 ZoneList<Expression*>* args = expr->arguments(); |
| 4124 DCHECK_EQ(args->length(), 1); |
| 4125 // Load the argument into r0 and call the stub. |
| 4126 VisitForAccumulatorValue(args->at(0)); |
| 4127 |
| 4128 NumberToStringStub stub(isolate()); |
| 4129 __ CallStub(&stub); |
| 4130 context()->Plug(r0); |
| 4131 } |
| 4132 |
| 4022 | 4133 |
| 4023 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 4134 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 4024 ZoneList<Expression*>* args = expr->arguments(); | 4135 ZoneList<Expression*>* args = expr->arguments(); |
| 4025 DCHECK(args->length() == 1); | 4136 DCHECK(args->length() == 1); |
| 4026 VisitForAccumulatorValue(args->at(0)); | 4137 VisitForAccumulatorValue(args->at(0)); |
| 4027 | 4138 |
| 4028 Label done; | 4139 Label done; |
| 4029 StringCharFromCodeGenerator generator(r0, r1); | 4140 StringCharFromCodeGenerator generator(r0, r1); |
| 4030 generator.GenerateFast(masm_); | 4141 generator.GenerateFast(masm_); |
| 4031 __ jmp(&done); | 4142 __ jmp(&done); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4134 ZoneList<Expression*>* args = expr->arguments(); | 4245 ZoneList<Expression*>* args = expr->arguments(); |
| 4135 DCHECK_EQ(2, args->length()); | 4246 DCHECK_EQ(2, args->length()); |
| 4136 VisitForStackValue(args->at(0)); | 4247 VisitForStackValue(args->at(0)); |
| 4137 VisitForAccumulatorValue(args->at(1)); | 4248 VisitForAccumulatorValue(args->at(1)); |
| 4138 | 4249 |
| 4139 __ pop(r1); | 4250 __ pop(r1); |
| 4140 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4251 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 4141 __ CallStub(&stub); | 4252 __ CallStub(&stub); |
| 4142 context()->Plug(r0); | 4253 context()->Plug(r0); |
| 4143 } | 4254 } |
| 4255 |
| 4256 |
| 4257 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 4258 ZoneList<Expression*>* args = expr->arguments(); |
| 4259 DCHECK_EQ(2, args->length()); |
| 4260 VisitForStackValue(args->at(0)); |
| 4261 VisitForStackValue(args->at(1)); |
| 4262 |
| 4263 StringCompareStub stub(isolate()); |
| 4264 __ CallStub(&stub); |
| 4265 context()->Plug(r0); |
| 4266 } |
| 4144 | 4267 |
| 4145 | 4268 |
| 4146 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4269 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 4147 ZoneList<Expression*>* args = expr->arguments(); | 4270 ZoneList<Expression*>* args = expr->arguments(); |
| 4148 DCHECK(args->length() >= 2); | 4271 DCHECK(args->length() >= 2); |
| 4149 | 4272 |
| 4150 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4273 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 4151 for (int i = 0; i < arg_count + 1; i++) { | 4274 for (int i = 0; i < arg_count + 1; i++) { |
| 4152 VisitForStackValue(args->at(i)); | 4275 VisitForStackValue(args->at(i)); |
| 4153 } | 4276 } |
| (...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5457 DCHECK(interrupt_address == | 5580 DCHECK(interrupt_address == |
| 5458 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5581 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5459 return OSR_AFTER_STACK_CHECK; | 5582 return OSR_AFTER_STACK_CHECK; |
| 5460 } | 5583 } |
| 5461 | 5584 |
| 5462 | 5585 |
| 5463 } // namespace internal | 5586 } // namespace internal |
| 5464 } // namespace v8 | 5587 } // namespace v8 |
| 5465 | 5588 |
| 5466 #endif // V8_TARGET_ARCH_ARM | 5589 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |