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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 443 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
444 int32_t arg_count = info_->scope()->num_parameters() + 1; | 444 int32_t arg_count = info_->scope()->num_parameters() + 1; |
445 int32_t sp_delta = arg_count * kPointerSize; | 445 int32_t sp_delta = arg_count * kPointerSize; |
446 SetReturnPosition(literal()); | 446 SetReturnPosition(literal()); |
447 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); | 447 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); |
448 __ blr(); | 448 __ blr(); |
449 } | 449 } |
450 } | 450 } |
451 } | 451 } |
452 | 452 |
| 453 void FullCodeGenerator::RestoreContext() { |
| 454 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 455 } |
453 | 456 |
454 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 457 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
455 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 458 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
456 codegen()->GetVar(result_register(), var); | 459 codegen()->GetVar(result_register(), var); |
457 codegen()->PushOperand(result_register()); | 460 codegen()->PushOperand(result_register()); |
458 } | 461 } |
459 | 462 |
460 | 463 |
461 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} | 464 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} |
462 | 465 |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index())); | 1376 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index())); |
1374 __ mov(r4, Operand(constant_properties)); | 1377 __ mov(r4, Operand(constant_properties)); |
1375 int flags = expr->ComputeFlags(); | 1378 int flags = expr->ComputeFlags(); |
1376 __ LoadSmiLiteral(r3, Smi::FromInt(flags)); | 1379 __ LoadSmiLiteral(r3, Smi::FromInt(flags)); |
1377 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1380 if (MustCreateObjectLiteralWithRuntime(expr)) { |
1378 __ Push(r6, r5, r4, r3); | 1381 __ Push(r6, r5, r4, r3); |
1379 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1382 __ CallRuntime(Runtime::kCreateObjectLiteral); |
1380 } else { | 1383 } else { |
1381 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1384 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1382 __ CallStub(&stub); | 1385 __ CallStub(&stub); |
1383 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1386 RestoreContext(); |
1384 } | 1387 } |
1385 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1388 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1386 | 1389 |
1387 // If result_saved is true the result is on top of the stack. If | 1390 // If result_saved is true the result is on top of the stack. If |
1388 // result_saved is false the result is in r3. | 1391 // result_saved is false the result is in r3. |
1389 bool result_saved = false; | 1392 bool result_saved = false; |
1390 | 1393 |
1391 AccessorTable accessor_table(zone()); | 1394 AccessorTable accessor_table(zone()); |
1392 int property_index = 0; | 1395 int property_index = 0; |
1393 for (; property_index < expr->properties()->length(); property_index++) { | 1396 for (; property_index < expr->properties()->length(); property_index++) { |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1818 r0); | 1821 r0); |
1819 __ StoreP(cp, FieldMemOperand(r3, JSGeneratorObject::kContextOffset), r0); | 1822 __ StoreP(cp, FieldMemOperand(r3, JSGeneratorObject::kContextOffset), r0); |
1820 __ mr(r4, cp); | 1823 __ mr(r4, cp); |
1821 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5, | 1824 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5, |
1822 kLRHasBeenSaved, kDontSaveFPRegs); | 1825 kLRHasBeenSaved, kDontSaveFPRegs); |
1823 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1826 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1824 __ cmp(sp, r4); | 1827 __ cmp(sp, r4); |
1825 __ beq(&post_runtime); | 1828 __ beq(&post_runtime); |
1826 __ push(r3); // generator object | 1829 __ push(r3); // generator object |
1827 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1830 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1828 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1831 RestoreContext(); |
1829 __ bind(&post_runtime); | 1832 __ bind(&post_runtime); |
1830 PopOperand(result_register()); | 1833 PopOperand(result_register()); |
1831 EmitReturnSequence(); | 1834 EmitReturnSequence(); |
1832 | 1835 |
1833 __ bind(&resume); | 1836 __ bind(&resume); |
1834 context()->Plug(result_register()); | 1837 context()->Plug(result_register()); |
1835 } | 1838 } |
1836 | 1839 |
1837 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1840 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
1838 OperandStackDepthIncrement(2); | 1841 OperandStackDepthIncrement(2); |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2517 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2515 .code(); | 2518 .code(); |
2516 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); | 2519 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); |
2517 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2520 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
2518 // Don't assign a type feedback id to the IC, since type feedback is provided | 2521 // Don't assign a type feedback id to the IC, since type feedback is provided |
2519 // by the vector above. | 2522 // by the vector above. |
2520 CallIC(ic); | 2523 CallIC(ic); |
2521 OperandStackDepthDecrement(arg_count + 1); | 2524 OperandStackDepthDecrement(arg_count + 1); |
2522 | 2525 |
2523 RecordJSReturnSite(expr); | 2526 RecordJSReturnSite(expr); |
2524 // Restore context register. | 2527 RestoreContext(); |
2525 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2526 context()->DropAndPlug(1, r3); | 2528 context()->DropAndPlug(1, r3); |
2527 } | 2529 } |
2528 | 2530 |
2529 | 2531 |
2530 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2532 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
2531 int arg_count = expr->arguments()->length(); | 2533 int arg_count = expr->arguments()->length(); |
2532 // r7: copy of the first argument or undefined if it doesn't exist. | 2534 // r7: copy of the first argument or undefined if it doesn't exist. |
2533 if (arg_count > 0) { | 2535 if (arg_count > 0) { |
2534 __ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0); | 2536 __ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0); |
2535 } else { | 2537 } else { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 | 2625 |
2624 // Record source position for debugger. | 2626 // Record source position for debugger. |
2625 SetCallPosition(expr); | 2627 SetCallPosition(expr); |
2626 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2628 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
2627 __ mov(r3, Operand(arg_count)); | 2629 __ mov(r3, Operand(arg_count)); |
2628 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2630 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2629 expr->tail_call_mode()), | 2631 expr->tail_call_mode()), |
2630 RelocInfo::CODE_TARGET); | 2632 RelocInfo::CODE_TARGET); |
2631 OperandStackDepthDecrement(arg_count + 1); | 2633 OperandStackDepthDecrement(arg_count + 1); |
2632 RecordJSReturnSite(expr); | 2634 RecordJSReturnSite(expr); |
2633 // Restore context register. | 2635 RestoreContext(); |
2634 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2635 context()->DropAndPlug(1, r3); | 2636 context()->DropAndPlug(1, r3); |
2636 } | 2637 } |
2637 | 2638 |
2638 | 2639 |
2639 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2640 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2640 Comment cmnt(masm_, "[ CallNew"); | 2641 Comment cmnt(masm_, "[ CallNew"); |
2641 // According to ECMA-262, section 11.2.2, page 44, the function | 2642 // According to ECMA-262, section 11.2.2, page 44, the function |
2642 // expression in new calls must be evaluated before the | 2643 // expression in new calls must be evaluated before the |
2643 // arguments. | 2644 // arguments. |
2644 | 2645 |
(...skipping 19 matching lines...) Expand all Loading... |
2664 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); | 2665 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); |
2665 | 2666 |
2666 // Record call targets in unoptimized code. | 2667 // Record call targets in unoptimized code. |
2667 __ EmitLoadTypeFeedbackVector(r5); | 2668 __ EmitLoadTypeFeedbackVector(r5); |
2668 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2669 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); |
2669 | 2670 |
2670 CallConstructStub stub(isolate()); | 2671 CallConstructStub stub(isolate()); |
2671 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2672 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
2672 OperandStackDepthDecrement(arg_count + 1); | 2673 OperandStackDepthDecrement(arg_count + 1); |
2673 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2674 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2674 // Restore context register. | 2675 RestoreContext(); |
2675 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2676 context()->Plug(r3); | 2676 context()->Plug(r3); |
2677 } | 2677 } |
2678 | 2678 |
2679 | 2679 |
2680 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2680 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2681 SuperCallReference* super_call_ref = | 2681 SuperCallReference* super_call_ref = |
2682 expr->expression()->AsSuperCallReference(); | 2682 expr->expression()->AsSuperCallReference(); |
2683 DCHECK_NOT_NULL(super_call_ref); | 2683 DCHECK_NOT_NULL(super_call_ref); |
2684 | 2684 |
2685 // Push the super constructor target on the stack (may be null, | 2685 // Push the super constructor target on the stack (may be null, |
(...skipping 22 matching lines...) Expand all Loading... |
2708 __ mr(r6, result_register()); | 2708 __ mr(r6, result_register()); |
2709 | 2709 |
2710 // Load function and argument count into r1 and r0. | 2710 // Load function and argument count into r1 and r0. |
2711 __ mov(r3, Operand(arg_count)); | 2711 __ mov(r3, Operand(arg_count)); |
2712 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); | 2712 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); |
2713 | 2713 |
2714 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2714 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2715 OperandStackDepthDecrement(arg_count + 1); | 2715 OperandStackDepthDecrement(arg_count + 1); |
2716 | 2716 |
2717 RecordJSReturnSite(expr); | 2717 RecordJSReturnSite(expr); |
2718 | 2718 RestoreContext(); |
2719 // Restore context register. | |
2720 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2721 context()->Plug(r3); | 2719 context()->Plug(r3); |
2722 } | 2720 } |
2723 | 2721 |
2724 | 2722 |
2725 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2723 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2726 ZoneList<Expression*>* args = expr->arguments(); | 2724 ZoneList<Expression*>* args = expr->arguments(); |
2727 DCHECK(args->length() == 1); | 2725 DCHECK(args->length() == 1); |
2728 | 2726 |
2729 VisitForAccumulatorValue(args->at(0)); | 2727 VisitForAccumulatorValue(args->at(0)); |
2730 | 2728 |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 VisitForStackValue(arg); | 3094 VisitForStackValue(arg); |
3097 } | 3095 } |
3098 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3096 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3099 // Move target to r4. | 3097 // Move target to r4. |
3100 int const argc = args->length() - 2; | 3098 int const argc = args->length() - 2; |
3101 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize)); | 3099 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize)); |
3102 // Call the target. | 3100 // Call the target. |
3103 __ mov(r3, Operand(argc)); | 3101 __ mov(r3, Operand(argc)); |
3104 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3102 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3105 OperandStackDepthDecrement(argc + 1); | 3103 OperandStackDepthDecrement(argc + 1); |
3106 // Restore context register. | 3104 RestoreContext(); |
3107 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3108 // Discard the function left on TOS. | 3105 // Discard the function left on TOS. |
3109 context()->DropAndPlug(1, r3); | 3106 context()->DropAndPlug(1, r3); |
3110 } | 3107 } |
3111 | 3108 |
3112 | 3109 |
3113 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3110 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3114 ZoneList<Expression*>* args = expr->arguments(); | 3111 ZoneList<Expression*>* args = expr->arguments(); |
3115 VisitForAccumulatorValue(args->at(0)); | 3112 VisitForAccumulatorValue(args->at(0)); |
3116 | 3113 |
3117 Label materialize_true, materialize_false; | 3114 Label materialize_true, materialize_false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3215 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3212 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3216 ZoneList<Expression*>* args = expr->arguments(); | 3213 ZoneList<Expression*>* args = expr->arguments(); |
3217 int arg_count = args->length(); | 3214 int arg_count = args->length(); |
3218 | 3215 |
3219 SetCallPosition(expr); | 3216 SetCallPosition(expr); |
3220 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3217 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3221 __ mov(r3, Operand(arg_count)); | 3218 __ mov(r3, Operand(arg_count)); |
3222 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3219 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3223 RelocInfo::CODE_TARGET); | 3220 RelocInfo::CODE_TARGET); |
3224 OperandStackDepthDecrement(arg_count + 1); | 3221 OperandStackDepthDecrement(arg_count + 1); |
3225 | 3222 RestoreContext(); |
3226 // Restore context register. | |
3227 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3228 } | 3223 } |
3229 | 3224 |
3230 | 3225 |
3231 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3226 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3232 switch (expr->op()) { | 3227 switch (expr->op()) { |
3233 case Token::DELETE: { | 3228 case Token::DELETE: { |
3234 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3229 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3235 Property* property = expr->expression()->AsProperty(); | 3230 Property* property = expr->expression()->AsProperty(); |
3236 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3231 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3237 | 3232 |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3682 Label* fall_through = NULL; | 3677 Label* fall_through = NULL; |
3683 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, | 3678 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, |
3684 &if_false, &fall_through); | 3679 &if_false, &fall_through); |
3685 | 3680 |
3686 Token::Value op = expr->op(); | 3681 Token::Value op = expr->op(); |
3687 VisitForStackValue(expr->left()); | 3682 VisitForStackValue(expr->left()); |
3688 switch (op) { | 3683 switch (op) { |
3689 case Token::IN: | 3684 case Token::IN: |
3690 VisitForStackValue(expr->right()); | 3685 VisitForStackValue(expr->right()); |
3691 SetExpressionPosition(expr); | 3686 SetExpressionPosition(expr); |
3692 CallRuntimeWithOperands(Runtime::kHasProperty); | 3687 EmitHasProperty(); |
3693 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3688 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3694 __ CompareRoot(r3, Heap::kTrueValueRootIndex); | 3689 __ CompareRoot(r3, Heap::kTrueValueRootIndex); |
3695 Split(eq, if_true, if_false, fall_through); | 3690 Split(eq, if_true, if_false, fall_through); |
3696 break; | 3691 break; |
3697 | 3692 |
3698 case Token::INSTANCEOF: { | 3693 case Token::INSTANCEOF: { |
3699 VisitForAccumulatorValue(expr->right()); | 3694 VisitForAccumulatorValue(expr->right()); |
3700 SetExpressionPosition(expr); | 3695 SetExpressionPosition(expr); |
3701 PopOperand(r4); | 3696 PopOperand(r4); |
3702 InstanceOfStub stub(isolate()); | 3697 InstanceOfStub stub(isolate()); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3940 | 3935 |
3941 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address))); | 3936 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address))); |
3942 | 3937 |
3943 DCHECK(interrupt_address == | 3938 DCHECK(interrupt_address == |
3944 isolate->builtins()->OnStackReplacement()->entry()); | 3939 isolate->builtins()->OnStackReplacement()->entry()); |
3945 return ON_STACK_REPLACEMENT; | 3940 return ON_STACK_REPLACEMENT; |
3946 } | 3941 } |
3947 } // namespace internal | 3942 } // namespace internal |
3948 } // namespace v8 | 3943 } // namespace v8 |
3949 #endif // V8_TARGET_ARCH_PPC | 3944 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |