| 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 | |
| 523 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 512 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 524 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 513 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 525 codegen()->GetVar(result_register(), var); | 514 codegen()->GetVar(result_register(), var); |
| 526 __ push(result_register()); | 515 __ push(result_register()); |
| 527 } | 516 } |
| 528 | 517 |
| 529 | 518 |
| 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 | |
| 539 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 519 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 540 } | 520 } |
| 541 | 521 |
| 542 | 522 |
| 543 void FullCodeGenerator::AccumulatorValueContext::Plug( | 523 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 544 Heap::RootListIndex index) const { | 524 Heap::RootListIndex index) const { |
| 545 __ LoadRoot(result_register(), index); | 525 __ LoadRoot(result_register(), index); |
| 546 } | 526 } |
| 547 | 527 |
| 548 | 528 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 } | 667 } |
| 688 | 668 |
| 689 | 669 |
| 690 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 670 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 691 Label* materialize_false) const { | 671 Label* materialize_false) const { |
| 692 DCHECK(materialize_true == true_label_); | 672 DCHECK(materialize_true == true_label_); |
| 693 DCHECK(materialize_false == false_label_); | 673 DCHECK(materialize_false == false_label_); |
| 694 } | 674 } |
| 695 | 675 |
| 696 | 676 |
| 697 void FullCodeGenerator::EffectContext::Plug(bool flag) const { | |
| 698 } | |
| 699 | |
| 700 | |
| 701 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 677 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 702 Heap::RootListIndex value_root_index = | 678 Heap::RootListIndex value_root_index = |
| 703 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 679 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 704 __ LoadRoot(result_register(), value_root_index); | 680 __ LoadRoot(result_register(), value_root_index); |
| 705 } | 681 } |
| 706 | 682 |
| 707 | 683 |
| 708 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 684 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 709 Heap::RootListIndex value_root_index = | 685 Heap::RootListIndex value_root_index = |
| 710 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 686 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 __ Push(cp, r2, r1); | 935 __ Push(cp, r2, r1); |
| 960 // Push initial value for function declaration. | 936 // Push initial value for function declaration. |
| 961 VisitForStackValue(declaration->fun()); | 937 VisitForStackValue(declaration->fun()); |
| 962 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 938 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 963 break; | 939 break; |
| 964 } | 940 } |
| 965 } | 941 } |
| 966 } | 942 } |
| 967 | 943 |
| 968 | 944 |
| 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 | |
| 998 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 945 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 999 // Call the runtime to declare the globals. | 946 // Call the runtime to declare the globals. |
| 1000 // The context is the first argument. | 947 // The context is the first argument. |
| 1001 __ mov(r1, Operand(pairs)); | 948 __ mov(r1, Operand(pairs)); |
| 1002 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 949 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
| 1003 __ Push(cp, r1, r0); | 950 __ Push(cp, r1, r0); |
| 1004 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 951 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 1005 // Return value is ignored. | 952 // Return value is ignored. |
| 1006 } | 953 } |
| 1007 | 954 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1319 __ mov(r0, Operand(info)); | 1266 __ mov(r0, Operand(info)); |
| 1320 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1267 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
| 1321 : Heap::kFalseValueRootIndex); | 1268 : Heap::kFalseValueRootIndex); |
| 1322 __ Push(cp, r0, r1); | 1269 __ Push(cp, r0, r1); |
| 1323 __ CallRuntime(Runtime::kNewClosure, 3); | 1270 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1324 } | 1271 } |
| 1325 context()->Plug(r0); | 1272 context()->Plug(r0); |
| 1326 } | 1273 } |
| 1327 | 1274 |
| 1328 | 1275 |
| 1329 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | |
| 1330 Comment cmnt(masm_, "[ VariableProxy"); | |
| 1331 EmitVariableLoad(expr); | |
| 1332 } | |
| 1333 | |
| 1334 | |
| 1335 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1276 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1336 int offset, | 1277 int offset, |
| 1337 FeedbackVectorICSlot slot) { | 1278 FeedbackVectorICSlot slot) { |
| 1338 if (NeedsHomeObject(initializer)) { | 1279 if (NeedsHomeObject(initializer)) { |
| 1339 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1280 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1340 __ mov(StoreDescriptor::NameRegister(), | 1281 __ mov(StoreDescriptor::NameRegister(), |
| 1341 Operand(isolate()->factory()->home_object_symbol())); | 1282 Operand(isolate()->factory()->home_object_symbol())); |
| 1342 __ ldr(StoreDescriptor::ValueRegister(), | 1283 __ ldr(StoreDescriptor::ValueRegister(), |
| 1343 MemOperand(sp, offset * kPointerSize)); | 1284 MemOperand(sp, offset * kPointerSize)); |
| 1344 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1285 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| (...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3899 __ bind(&null); | 3840 __ bind(&null); |
| 3900 __ LoadRoot(r0, Heap::kNullValueRootIndex); | 3841 __ LoadRoot(r0, Heap::kNullValueRootIndex); |
| 3901 | 3842 |
| 3902 // All done. | 3843 // All done. |
| 3903 __ bind(&done); | 3844 __ bind(&done); |
| 3904 | 3845 |
| 3905 context()->Plug(r0); | 3846 context()->Plug(r0); |
| 3906 } | 3847 } |
| 3907 | 3848 |
| 3908 | 3849 |
| 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 | |
| 3936 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3850 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 3937 ZoneList<Expression*>* args = expr->arguments(); | 3851 ZoneList<Expression*>* args = expr->arguments(); |
| 3938 DCHECK(args->length() == 1); | 3852 DCHECK(args->length() == 1); |
| 3939 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3853 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3940 | 3854 |
| 3941 Label done; | 3855 Label done; |
| 3942 // If the object is a smi return the object. | 3856 // If the object is a smi return the object. |
| 3943 __ JumpIfSmi(r0, &done); | 3857 __ JumpIfSmi(r0, &done); |
| 3944 // If the object is not a value type, return the object. | 3858 // If the object is not a value type, return the object. |
| 3945 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); | 3859 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4071 __ SmiUntag(value, value); | 3985 __ SmiUntag(value, value); |
| 4072 __ add(ip, | 3986 __ add(ip, |
| 4073 string, | 3987 string, |
| 4074 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 3988 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 4075 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 3989 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 4076 __ strh(value, MemOperand(ip, index)); | 3990 __ strh(value, MemOperand(ip, index)); |
| 4077 context()->Plug(string); | 3991 context()->Plug(string); |
| 4078 } | 3992 } |
| 4079 | 3993 |
| 4080 | 3994 |
| 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 | |
| 4094 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3995 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 4095 ZoneList<Expression*>* args = expr->arguments(); | 3996 ZoneList<Expression*>* args = expr->arguments(); |
| 4096 DCHECK(args->length() == 2); | 3997 DCHECK(args->length() == 2); |
| 4097 VisitForStackValue(args->at(0)); // Load the object. | 3998 VisitForStackValue(args->at(0)); // Load the object. |
| 4098 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3999 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 4099 __ pop(r1); // r0 = value. r1 = object. | 4000 __ pop(r1); // r0 = value. r1 = object. |
| 4100 | 4001 |
| 4101 Label done; | 4002 Label done; |
| 4102 // If the object is a smi, return the value. | 4003 // If the object is a smi, return the value. |
| 4103 __ JumpIfSmi(r1, &done); | 4004 __ JumpIfSmi(r1, &done); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4247 VisitForStackValue(args->at(0)); | 4148 VisitForStackValue(args->at(0)); |
| 4248 VisitForAccumulatorValue(args->at(1)); | 4149 VisitForAccumulatorValue(args->at(1)); |
| 4249 | 4150 |
| 4250 __ pop(r1); | 4151 __ pop(r1); |
| 4251 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4152 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 4252 __ CallStub(&stub); | 4153 __ CallStub(&stub); |
| 4253 context()->Plug(r0); | 4154 context()->Plug(r0); |
| 4254 } | 4155 } |
| 4255 | 4156 |
| 4256 | 4157 |
| 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 } | |
| 4267 | |
| 4268 | |
| 4269 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4158 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 4270 ZoneList<Expression*>* args = expr->arguments(); | 4159 ZoneList<Expression*>* args = expr->arguments(); |
| 4271 DCHECK(args->length() >= 2); | 4160 DCHECK(args->length() >= 2); |
| 4272 | 4161 |
| 4273 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4162 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 4274 for (int i = 0; i < arg_count + 1; i++) { | 4163 for (int i = 0; i < arg_count + 1; i++) { |
| 4275 VisitForStackValue(args->at(i)); | 4164 VisitForStackValue(args->at(i)); |
| 4276 } | 4165 } |
| 4277 VisitForAccumulatorValue(args->last()); // Function. | 4166 VisitForAccumulatorValue(args->last()); // Function. |
| 4278 | 4167 |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5580 DCHECK(interrupt_address == | 5469 DCHECK(interrupt_address == |
| 5581 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5470 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5582 return OSR_AFTER_STACK_CHECK; | 5471 return OSR_AFTER_STACK_CHECK; |
| 5583 } | 5472 } |
| 5584 | 5473 |
| 5585 | 5474 |
| 5586 } // namespace internal | 5475 } // namespace internal |
| 5587 } // namespace v8 | 5476 } // namespace v8 |
| 5588 | 5477 |
| 5589 #endif // V8_TARGET_ARCH_ARM | 5478 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |