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 |