OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 7 #if V8_TARGET_ARCH_PPC |
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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 int32_t sp_delta = arg_count * kPointerSize; | 490 int32_t sp_delta = arg_count * kPointerSize; |
491 SetReturnPosition(function()); | 491 SetReturnPosition(function()); |
492 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); | 492 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); |
493 __ blr(); | 493 __ blr(); |
494 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 494 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
495 } | 495 } |
496 } | 496 } |
497 } | 497 } |
498 | 498 |
499 | 499 |
| 500 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 501 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 502 } |
| 503 |
| 504 |
| 505 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 506 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 507 codegen()->GetVar(result_register(), var); |
| 508 } |
| 509 |
| 510 |
500 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 511 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
501 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 512 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
502 codegen()->GetVar(result_register(), var); | 513 codegen()->GetVar(result_register(), var); |
503 __ push(result_register()); | 514 __ push(result_register()); |
504 } | 515 } |
505 | 516 |
506 | 517 |
| 518 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 519 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 520 // For simplicity we always test the accumulator register. |
| 521 codegen()->GetVar(result_register(), var); |
| 522 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 523 codegen()->DoTest(this); |
| 524 } |
| 525 |
| 526 |
507 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} | 527 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} |
508 | 528 |
509 | 529 |
510 void FullCodeGenerator::AccumulatorValueContext::Plug( | 530 void FullCodeGenerator::AccumulatorValueContext::Plug( |
511 Heap::RootListIndex index) const { | 531 Heap::RootListIndex index) const { |
512 __ LoadRoot(result_register(), index); | 532 __ LoadRoot(result_register(), index); |
513 } | 533 } |
514 | 534 |
515 | 535 |
516 void FullCodeGenerator::StackValueContext::Plug( | 536 void FullCodeGenerator::StackValueContext::Plug( |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 } | 666 } |
647 | 667 |
648 | 668 |
649 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 669 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
650 Label* materialize_false) const { | 670 Label* materialize_false) const { |
651 DCHECK(materialize_true == true_label_); | 671 DCHECK(materialize_true == true_label_); |
652 DCHECK(materialize_false == false_label_); | 672 DCHECK(materialize_false == false_label_); |
653 } | 673 } |
654 | 674 |
655 | 675 |
| 676 void FullCodeGenerator::EffectContext::Plug(bool flag) const {} |
| 677 |
| 678 |
656 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 679 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
657 Heap::RootListIndex value_root_index = | 680 Heap::RootListIndex value_root_index = |
658 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 681 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
659 __ LoadRoot(result_register(), value_root_index); | 682 __ LoadRoot(result_register(), value_root_index); |
660 } | 683 } |
661 | 684 |
662 | 685 |
663 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 686 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
664 Heap::RootListIndex value_root_index = | 687 Heap::RootListIndex value_root_index = |
665 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 688 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 __ Push(cp, r5, r4); | 920 __ Push(cp, r5, r4); |
898 // Push initial value for function declaration. | 921 // Push initial value for function declaration. |
899 VisitForStackValue(declaration->fun()); | 922 VisitForStackValue(declaration->fun()); |
900 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 923 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
901 break; | 924 break; |
902 } | 925 } |
903 } | 926 } |
904 } | 927 } |
905 | 928 |
906 | 929 |
| 930 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 931 VariableProxy* proxy = declaration->proxy(); |
| 932 Variable* variable = proxy->var(); |
| 933 switch (variable->location()) { |
| 934 case VariableLocation::GLOBAL: |
| 935 case VariableLocation::UNALLOCATED: |
| 936 // TODO(rossberg) |
| 937 break; |
| 938 |
| 939 case VariableLocation::CONTEXT: { |
| 940 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 941 EmitDebugCheckDeclarationContext(variable); |
| 942 // TODO(rossberg) |
| 943 break; |
| 944 } |
| 945 |
| 946 case VariableLocation::PARAMETER: |
| 947 case VariableLocation::LOCAL: |
| 948 case VariableLocation::LOOKUP: |
| 949 UNREACHABLE(); |
| 950 } |
| 951 } |
| 952 |
| 953 |
| 954 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 955 // TODO(rossberg) |
| 956 } |
| 957 |
| 958 |
907 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 959 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
908 // Call the runtime to declare the globals. | 960 // Call the runtime to declare the globals. |
909 // The context is the first argument. | 961 // The context is the first argument. |
910 __ mov(r4, Operand(pairs)); | 962 __ mov(r4, Operand(pairs)); |
911 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); | 963 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); |
912 __ Push(cp, r4, r3); | 964 __ Push(cp, r4, r3); |
913 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 965 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
914 // Return value is ignored. | 966 // Return value is ignored. |
915 } | 967 } |
916 | 968 |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 __ mov(r3, Operand(info)); | 1281 __ mov(r3, Operand(info)); |
1230 __ LoadRoot( | 1282 __ LoadRoot( |
1231 r4, pretenure ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 1283 r4, pretenure ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
1232 __ Push(cp, r3, r4); | 1284 __ Push(cp, r3, r4); |
1233 __ CallRuntime(Runtime::kNewClosure, 3); | 1285 __ CallRuntime(Runtime::kNewClosure, 3); |
1234 } | 1286 } |
1235 context()->Plug(r3); | 1287 context()->Plug(r3); |
1236 } | 1288 } |
1237 | 1289 |
1238 | 1290 |
| 1291 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1292 Comment cmnt(masm_, "[ VariableProxy"); |
| 1293 EmitVariableLoad(expr); |
| 1294 } |
| 1295 |
| 1296 |
1239 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1297 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
1240 int offset, | 1298 int offset, |
1241 FeedbackVectorICSlot slot) { | 1299 FeedbackVectorICSlot slot) { |
1242 if (NeedsHomeObject(initializer)) { | 1300 if (NeedsHomeObject(initializer)) { |
1243 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1301 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1244 __ mov(StoreDescriptor::NameRegister(), | 1302 __ mov(StoreDescriptor::NameRegister(), |
1245 Operand(isolate()->factory()->home_object_symbol())); | 1303 Operand(isolate()->factory()->home_object_symbol())); |
1246 __ LoadP(StoreDescriptor::ValueRegister(), | 1304 __ LoadP(StoreDescriptor::ValueRegister(), |
1247 MemOperand(sp, offset * kPointerSize)); | 1305 MemOperand(sp, offset * kPointerSize)); |
1248 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1306 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
(...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3849 __ bind(&null); | 3907 __ bind(&null); |
3850 __ LoadRoot(r3, Heap::kNullValueRootIndex); | 3908 __ LoadRoot(r3, Heap::kNullValueRootIndex); |
3851 | 3909 |
3852 // All done. | 3910 // All done. |
3853 __ bind(&done); | 3911 __ bind(&done); |
3854 | 3912 |
3855 context()->Plug(r3); | 3913 context()->Plug(r3); |
3856 } | 3914 } |
3857 | 3915 |
3858 | 3916 |
| 3917 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3918 // Load the arguments on the stack and call the stub. |
| 3919 SubStringStub stub(isolate()); |
| 3920 ZoneList<Expression*>* args = expr->arguments(); |
| 3921 DCHECK(args->length() == 3); |
| 3922 VisitForStackValue(args->at(0)); |
| 3923 VisitForStackValue(args->at(1)); |
| 3924 VisitForStackValue(args->at(2)); |
| 3925 __ CallStub(&stub); |
| 3926 context()->Plug(r3); |
| 3927 } |
| 3928 |
| 3929 |
| 3930 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3931 // Load the arguments on the stack and call the stub. |
| 3932 RegExpExecStub stub(isolate()); |
| 3933 ZoneList<Expression*>* args = expr->arguments(); |
| 3934 DCHECK(args->length() == 4); |
| 3935 VisitForStackValue(args->at(0)); |
| 3936 VisitForStackValue(args->at(1)); |
| 3937 VisitForStackValue(args->at(2)); |
| 3938 VisitForStackValue(args->at(3)); |
| 3939 __ CallStub(&stub); |
| 3940 context()->Plug(r3); |
| 3941 } |
| 3942 |
| 3943 |
3859 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3944 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
3860 ZoneList<Expression*>* args = expr->arguments(); | 3945 ZoneList<Expression*>* args = expr->arguments(); |
3861 DCHECK(args->length() == 1); | 3946 DCHECK(args->length() == 1); |
3862 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3947 VisitForAccumulatorValue(args->at(0)); // Load the object. |
3863 | 3948 |
3864 Label done; | 3949 Label done; |
3865 // If the object is a smi return the object. | 3950 // If the object is a smi return the object. |
3866 __ JumpIfSmi(r3, &done); | 3951 __ JumpIfSmi(r3, &done); |
3867 // If the object is not a value type, return the object. | 3952 // If the object is not a value type, return the object. |
3868 __ CompareObjectType(r3, r4, r4, JS_VALUE_TYPE); | 3953 __ CompareObjectType(r3, r4, r4, JS_VALUE_TYPE); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3994 } | 4079 } |
3995 | 4080 |
3996 __ SmiUntag(value); | 4081 __ SmiUntag(value); |
3997 __ addi(ip, string, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 4082 __ addi(ip, string, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
3998 __ SmiToShortArrayOffset(r0, index); | 4083 __ SmiToShortArrayOffset(r0, index); |
3999 __ sthx(value, MemOperand(ip, r0)); | 4084 __ sthx(value, MemOperand(ip, r0)); |
4000 context()->Plug(string); | 4085 context()->Plug(string); |
4001 } | 4086 } |
4002 | 4087 |
4003 | 4088 |
| 4089 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 4090 // Load the arguments on the stack and call the runtime function. |
| 4091 ZoneList<Expression*>* args = expr->arguments(); |
| 4092 DCHECK(args->length() == 2); |
| 4093 VisitForStackValue(args->at(0)); |
| 4094 VisitForStackValue(args->at(1)); |
| 4095 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 4096 __ CallStub(&stub); |
| 4097 context()->Plug(r3); |
| 4098 } |
| 4099 |
| 4100 |
4004 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 4101 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
4005 ZoneList<Expression*>* args = expr->arguments(); | 4102 ZoneList<Expression*>* args = expr->arguments(); |
4006 DCHECK(args->length() == 2); | 4103 DCHECK(args->length() == 2); |
4007 VisitForStackValue(args->at(0)); // Load the object. | 4104 VisitForStackValue(args->at(0)); // Load the object. |
4008 VisitForAccumulatorValue(args->at(1)); // Load the value. | 4105 VisitForAccumulatorValue(args->at(1)); // Load the value. |
4009 __ pop(r4); // r3 = value. r4 = object. | 4106 __ pop(r4); // r3 = value. r4 = object. |
4010 | 4107 |
4011 Label done; | 4108 Label done; |
4012 // If the object is a smi, return the value. | 4109 // If the object is a smi, return the value. |
4013 __ JumpIfSmi(r4, &done); | 4110 __ JumpIfSmi(r4, &done); |
4014 | 4111 |
4015 // If the object is not a value type, return the value. | 4112 // If the object is not a value type, return the value. |
4016 __ CompareObjectType(r4, r5, r5, JS_VALUE_TYPE); | 4113 __ CompareObjectType(r4, r5, r5, JS_VALUE_TYPE); |
4017 __ bne(&done); | 4114 __ bne(&done); |
4018 | 4115 |
4019 // Store the value. | 4116 // Store the value. |
4020 __ StoreP(r3, FieldMemOperand(r4, JSValue::kValueOffset), r0); | 4117 __ StoreP(r3, FieldMemOperand(r4, JSValue::kValueOffset), r0); |
4021 // Update the write barrier. Save the value as it will be | 4118 // Update the write barrier. Save the value as it will be |
4022 // overwritten by the write barrier code and is needed afterward. | 4119 // overwritten by the write barrier code and is needed afterward. |
4023 __ mr(r5, r3); | 4120 __ mr(r5, r3); |
4024 __ RecordWriteField(r4, JSValue::kValueOffset, r5, r6, kLRHasBeenSaved, | 4121 __ RecordWriteField(r4, JSValue::kValueOffset, r5, r6, kLRHasBeenSaved, |
4025 kDontSaveFPRegs); | 4122 kDontSaveFPRegs); |
4026 | 4123 |
4027 __ bind(&done); | 4124 __ bind(&done); |
4028 context()->Plug(r3); | 4125 context()->Plug(r3); |
4029 } | 4126 } |
4030 | 4127 |
| 4128 |
| 4129 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 4130 ZoneList<Expression*>* args = expr->arguments(); |
| 4131 DCHECK_EQ(args->length(), 1); |
| 4132 // Load the argument into r3 and call the stub. |
| 4133 VisitForAccumulatorValue(args->at(0)); |
| 4134 |
| 4135 NumberToStringStub stub(isolate()); |
| 4136 __ CallStub(&stub); |
| 4137 context()->Plug(r3); |
| 4138 } |
| 4139 |
4031 | 4140 |
4032 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 4141 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
4033 ZoneList<Expression*>* args = expr->arguments(); | 4142 ZoneList<Expression*>* args = expr->arguments(); |
4034 DCHECK(args->length() == 1); | 4143 DCHECK(args->length() == 1); |
4035 VisitForAccumulatorValue(args->at(0)); | 4144 VisitForAccumulatorValue(args->at(0)); |
4036 | 4145 |
4037 Label done; | 4146 Label done; |
4038 StringCharFromCodeGenerator generator(r3, r4); | 4147 StringCharFromCodeGenerator generator(r3, r4); |
4039 generator.GenerateFast(masm_); | 4148 generator.GenerateFast(masm_); |
4040 __ b(&done); | 4149 __ b(&done); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 ZoneList<Expression*>* args = expr->arguments(); | 4243 ZoneList<Expression*>* args = expr->arguments(); |
4135 DCHECK_EQ(2, args->length()); | 4244 DCHECK_EQ(2, args->length()); |
4136 VisitForStackValue(args->at(0)); | 4245 VisitForStackValue(args->at(0)); |
4137 VisitForAccumulatorValue(args->at(1)); | 4246 VisitForAccumulatorValue(args->at(1)); |
4138 | 4247 |
4139 __ pop(r4); | 4248 __ pop(r4); |
4140 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4249 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
4141 __ CallStub(&stub); | 4250 __ CallStub(&stub); |
4142 context()->Plug(r3); | 4251 context()->Plug(r3); |
4143 } | 4252 } |
| 4253 |
| 4254 |
| 4255 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 4256 ZoneList<Expression*>* args = expr->arguments(); |
| 4257 DCHECK_EQ(2, args->length()); |
| 4258 VisitForStackValue(args->at(0)); |
| 4259 VisitForStackValue(args->at(1)); |
| 4260 |
| 4261 StringCompareStub stub(isolate()); |
| 4262 __ CallStub(&stub); |
| 4263 context()->Plug(r3); |
| 4264 } |
4144 | 4265 |
4145 | 4266 |
4146 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4267 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
4147 ZoneList<Expression*>* args = expr->arguments(); | 4268 ZoneList<Expression*>* args = expr->arguments(); |
4148 DCHECK(args->length() >= 2); | 4269 DCHECK(args->length() >= 2); |
4149 | 4270 |
4150 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4271 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
4151 for (int i = 0; i < arg_count + 1; i++) { | 4272 for (int i = 0; i < arg_count + 1; i++) { |
4152 VisitForStackValue(args->at(i)); | 4273 VisitForStackValue(args->at(i)); |
4153 } | 4274 } |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5405 return ON_STACK_REPLACEMENT; | 5526 return ON_STACK_REPLACEMENT; |
5406 } | 5527 } |
5407 | 5528 |
5408 DCHECK(interrupt_address == | 5529 DCHECK(interrupt_address == |
5409 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5530 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5410 return OSR_AFTER_STACK_CHECK; | 5531 return OSR_AFTER_STACK_CHECK; |
5411 } | 5532 } |
5412 } // namespace internal | 5533 } // namespace internal |
5413 } // namespace v8 | 5534 } // namespace v8 |
5414 #endif // V8_TARGET_ARCH_PPC | 5535 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |