OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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_S390 | 5 #if V8_TARGET_ARCH_S390 |
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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 int32_t arg_count = info_->scope()->num_parameters() + 1; | 447 int32_t arg_count = info_->scope()->num_parameters() + 1; |
448 int32_t sp_delta = arg_count * kPointerSize; | 448 int32_t sp_delta = arg_count * kPointerSize; |
449 SetReturnPosition(literal()); | 449 SetReturnPosition(literal()); |
450 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); | 450 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); |
451 | 451 |
452 __ Ret(); | 452 __ Ret(); |
453 } | 453 } |
454 } | 454 } |
455 } | 455 } |
456 | 456 |
| 457 void FullCodeGenerator::RestoreContext() { |
| 458 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 459 } |
| 460 |
457 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 461 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
458 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 462 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
459 codegen()->GetVar(result_register(), var); | 463 codegen()->GetVar(result_register(), var); |
460 codegen()->PushOperand(result_register()); | 464 codegen()->PushOperand(result_register()); |
461 } | 465 } |
462 | 466 |
463 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} | 467 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} |
464 | 468 |
465 void FullCodeGenerator::AccumulatorValueContext::Plug( | 469 void FullCodeGenerator::AccumulatorValueContext::Plug( |
466 Heap::RootListIndex index) const { | 470 Heap::RootListIndex index) const { |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 __ LoadSmiLiteral(r4, Smi::FromInt(expr->literal_index())); | 1336 __ LoadSmiLiteral(r4, Smi::FromInt(expr->literal_index())); |
1333 __ mov(r3, Operand(constant_properties)); | 1337 __ mov(r3, Operand(constant_properties)); |
1334 int flags = expr->ComputeFlags(); | 1338 int flags = expr->ComputeFlags(); |
1335 __ LoadSmiLiteral(r2, Smi::FromInt(flags)); | 1339 __ LoadSmiLiteral(r2, Smi::FromInt(flags)); |
1336 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1340 if (MustCreateObjectLiteralWithRuntime(expr)) { |
1337 __ Push(r5, r4, r3, r2); | 1341 __ Push(r5, r4, r3, r2); |
1338 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1342 __ CallRuntime(Runtime::kCreateObjectLiteral); |
1339 } else { | 1343 } else { |
1340 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1344 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1341 __ CallStub(&stub); | 1345 __ CallStub(&stub); |
1342 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1346 RestoreContext(); |
1343 } | 1347 } |
1344 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1348 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1345 | 1349 |
1346 // If result_saved is true the result is on top of the stack. If | 1350 // If result_saved is true the result is on top of the stack. If |
1347 // result_saved is false the result is in r2. | 1351 // result_saved is false the result is in r2. |
1348 bool result_saved = false; | 1352 bool result_saved = false; |
1349 | 1353 |
1350 AccessorTable accessor_table(zone()); | 1354 AccessorTable accessor_table(zone()); |
1351 int property_index = 0; | 1355 int property_index = 0; |
1352 for (; property_index < expr->properties()->length(); property_index++) { | 1356 for (; property_index < expr->properties()->length(); property_index++) { |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 r0); | 1778 r0); |
1775 __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset), r0); | 1779 __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset), r0); |
1776 __ LoadRR(r3, cp); | 1780 __ LoadRR(r3, cp); |
1777 __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4, | 1781 __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4, |
1778 kLRHasBeenSaved, kDontSaveFPRegs); | 1782 kLRHasBeenSaved, kDontSaveFPRegs); |
1779 __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1783 __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1780 __ CmpP(sp, r3); | 1784 __ CmpP(sp, r3); |
1781 __ beq(&post_runtime); | 1785 __ beq(&post_runtime); |
1782 __ push(r2); // generator object | 1786 __ push(r2); // generator object |
1783 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1787 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1784 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1788 RestoreContext(); |
1785 __ bind(&post_runtime); | 1789 __ bind(&post_runtime); |
1786 PopOperand(result_register()); | 1790 PopOperand(result_register()); |
1787 EmitReturnSequence(); | 1791 EmitReturnSequence(); |
1788 | 1792 |
1789 __ bind(&resume); | 1793 __ bind(&resume); |
1790 context()->Plug(result_register()); | 1794 context()->Plug(result_register()); |
1791 } | 1795 } |
1792 | 1796 |
1793 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1797 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
1794 OperandStackDepthIncrement(2); | 1798 OperandStackDepthIncrement(2); |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2456 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2460 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2457 .code(); | 2461 .code(); |
2458 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallFeedbackICSlot())); | 2462 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallFeedbackICSlot())); |
2459 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2463 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
2460 // Don't assign a type feedback id to the IC, since type feedback is provided | 2464 // Don't assign a type feedback id to the IC, since type feedback is provided |
2461 // by the vector above. | 2465 // by the vector above. |
2462 CallIC(ic); | 2466 CallIC(ic); |
2463 OperandStackDepthDecrement(arg_count + 1); | 2467 OperandStackDepthDecrement(arg_count + 1); |
2464 | 2468 |
2465 RecordJSReturnSite(expr); | 2469 RecordJSReturnSite(expr); |
2466 // Restore context register. | 2470 RestoreContext(); |
2467 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2468 context()->DropAndPlug(1, r2); | 2471 context()->DropAndPlug(1, r2); |
2469 } | 2472 } |
2470 | 2473 |
2471 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2474 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
2472 int arg_count = expr->arguments()->length(); | 2475 int arg_count = expr->arguments()->length(); |
2473 // r6: copy of the first argument or undefined if it doesn't exist. | 2476 // r6: copy of the first argument or undefined if it doesn't exist. |
2474 if (arg_count > 0) { | 2477 if (arg_count > 0) { |
2475 __ LoadP(r6, MemOperand(sp, arg_count * kPointerSize), r0); | 2478 __ LoadP(r6, MemOperand(sp, arg_count * kPointerSize), r0); |
2476 } else { | 2479 } else { |
2477 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); | 2480 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2562 | 2565 |
2563 // Record source position for debugger. | 2566 // Record source position for debugger. |
2564 SetCallPosition(expr); | 2567 SetCallPosition(expr); |
2565 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2568 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
2566 __ mov(r2, Operand(arg_count)); | 2569 __ mov(r2, Operand(arg_count)); |
2567 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2570 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2568 expr->tail_call_mode()), | 2571 expr->tail_call_mode()), |
2569 RelocInfo::CODE_TARGET); | 2572 RelocInfo::CODE_TARGET); |
2570 OperandStackDepthDecrement(arg_count + 1); | 2573 OperandStackDepthDecrement(arg_count + 1); |
2571 RecordJSReturnSite(expr); | 2574 RecordJSReturnSite(expr); |
2572 // Restore context register. | 2575 RestoreContext(); |
2573 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2574 context()->DropAndPlug(1, r2); | 2576 context()->DropAndPlug(1, r2); |
2575 } | 2577 } |
2576 | 2578 |
2577 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2579 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2578 Comment cmnt(masm_, "[ CallNew"); | 2580 Comment cmnt(masm_, "[ CallNew"); |
2579 // According to ECMA-262, section 11.2.2, page 44, the function | 2581 // According to ECMA-262, section 11.2.2, page 44, the function |
2580 // expression in new calls must be evaluated before the | 2582 // expression in new calls must be evaluated before the |
2581 // arguments. | 2583 // arguments. |
2582 | 2584 |
2583 // Push constructor on the stack. If it's not a function it's used as | 2585 // Push constructor on the stack. If it's not a function it's used as |
(...skipping 18 matching lines...) Expand all Loading... |
2602 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize), r0); | 2604 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize), r0); |
2603 | 2605 |
2604 // Record call targets in unoptimized code. | 2606 // Record call targets in unoptimized code. |
2605 __ EmitLoadTypeFeedbackVector(r4); | 2607 __ EmitLoadTypeFeedbackVector(r4); |
2606 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2608 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallNewFeedbackSlot())); |
2607 | 2609 |
2608 CallConstructStub stub(isolate()); | 2610 CallConstructStub stub(isolate()); |
2609 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2611 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
2610 OperandStackDepthDecrement(arg_count + 1); | 2612 OperandStackDepthDecrement(arg_count + 1); |
2611 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2613 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2612 // Restore context register. | 2614 RestoreContext(); |
2613 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2614 context()->Plug(r2); | 2615 context()->Plug(r2); |
2615 } | 2616 } |
2616 | 2617 |
2617 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2618 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2618 SuperCallReference* super_call_ref = | 2619 SuperCallReference* super_call_ref = |
2619 expr->expression()->AsSuperCallReference(); | 2620 expr->expression()->AsSuperCallReference(); |
2620 DCHECK_NOT_NULL(super_call_ref); | 2621 DCHECK_NOT_NULL(super_call_ref); |
2621 | 2622 |
2622 // Push the super constructor target on the stack (may be null, | 2623 // Push the super constructor target on the stack (may be null, |
2623 // but the Construct builtin can deal with that properly). | 2624 // but the Construct builtin can deal with that properly). |
(...skipping 21 matching lines...) Expand all Loading... |
2645 __ LoadRR(r5, result_register()); | 2646 __ LoadRR(r5, result_register()); |
2646 | 2647 |
2647 // Load function and argument count into r1 and r0. | 2648 // Load function and argument count into r1 and r0. |
2648 __ mov(r2, Operand(arg_count)); | 2649 __ mov(r2, Operand(arg_count)); |
2649 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize)); | 2650 __ LoadP(r3, MemOperand(sp, arg_count * kPointerSize)); |
2650 | 2651 |
2651 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2652 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2652 OperandStackDepthDecrement(arg_count + 1); | 2653 OperandStackDepthDecrement(arg_count + 1); |
2653 | 2654 |
2654 RecordJSReturnSite(expr); | 2655 RecordJSReturnSite(expr); |
2655 | 2656 RestoreContext(); |
2656 // Restore context register. | |
2657 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2658 context()->Plug(r2); | 2657 context()->Plug(r2); |
2659 } | 2658 } |
2660 | 2659 |
2661 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2660 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2662 ZoneList<Expression*>* args = expr->arguments(); | 2661 ZoneList<Expression*>* args = expr->arguments(); |
2663 DCHECK(args->length() == 1); | 2662 DCHECK(args->length() == 1); |
2664 | 2663 |
2665 VisitForAccumulatorValue(args->at(0)); | 2664 VisitForAccumulatorValue(args->at(0)); |
2666 | 2665 |
2667 Label materialize_true, materialize_false, skip_lookup; | 2666 Label materialize_true, materialize_false, skip_lookup; |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3019 VisitForStackValue(arg); | 3018 VisitForStackValue(arg); |
3020 } | 3019 } |
3021 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3020 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3022 // Move target to r3. | 3021 // Move target to r3. |
3023 int const argc = args->length() - 2; | 3022 int const argc = args->length() - 2; |
3024 __ LoadP(r3, MemOperand(sp, (argc + 1) * kPointerSize)); | 3023 __ LoadP(r3, MemOperand(sp, (argc + 1) * kPointerSize)); |
3025 // Call the target. | 3024 // Call the target. |
3026 __ mov(r2, Operand(argc)); | 3025 __ mov(r2, Operand(argc)); |
3027 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3026 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3028 OperandStackDepthDecrement(argc + 1); | 3027 OperandStackDepthDecrement(argc + 1); |
3029 // Restore context register. | 3028 RestoreContext(); |
3030 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3031 // Discard the function left on TOS. | 3029 // Discard the function left on TOS. |
3032 context()->DropAndPlug(1, r2); | 3030 context()->DropAndPlug(1, r2); |
3033 } | 3031 } |
3034 | 3032 |
3035 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3033 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3036 ZoneList<Expression*>* args = expr->arguments(); | 3034 ZoneList<Expression*>* args = expr->arguments(); |
3037 VisitForAccumulatorValue(args->at(0)); | 3035 VisitForAccumulatorValue(args->at(0)); |
3038 | 3036 |
3039 Label materialize_true, materialize_false; | 3037 Label materialize_true, materialize_false; |
3040 Label* if_true = NULL; | 3038 Label* if_true = NULL; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3130 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3128 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3131 ZoneList<Expression*>* args = expr->arguments(); | 3129 ZoneList<Expression*>* args = expr->arguments(); |
3132 int arg_count = args->length(); | 3130 int arg_count = args->length(); |
3133 | 3131 |
3134 SetCallPosition(expr); | 3132 SetCallPosition(expr); |
3135 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3133 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3136 __ mov(r2, Operand(arg_count)); | 3134 __ mov(r2, Operand(arg_count)); |
3137 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3135 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3138 RelocInfo::CODE_TARGET); | 3136 RelocInfo::CODE_TARGET); |
3139 OperandStackDepthDecrement(arg_count + 1); | 3137 OperandStackDepthDecrement(arg_count + 1); |
3140 | 3138 RestoreContext(); |
3141 // Restore context register. | |
3142 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3143 } | 3139 } |
3144 | 3140 |
3145 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3141 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3146 switch (expr->op()) { | 3142 switch (expr->op()) { |
3147 case Token::DELETE: { | 3143 case Token::DELETE: { |
3148 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3144 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3149 Property* property = expr->expression()->AsProperty(); | 3145 Property* property = expr->expression()->AsProperty(); |
3150 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3146 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3151 | 3147 |
3152 if (property != NULL) { | 3148 if (property != NULL) { |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3590 Label* fall_through = NULL; | 3586 Label* fall_through = NULL; |
3591 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, | 3587 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, |
3592 &if_false, &fall_through); | 3588 &if_false, &fall_through); |
3593 | 3589 |
3594 Token::Value op = expr->op(); | 3590 Token::Value op = expr->op(); |
3595 VisitForStackValue(expr->left()); | 3591 VisitForStackValue(expr->left()); |
3596 switch (op) { | 3592 switch (op) { |
3597 case Token::IN: | 3593 case Token::IN: |
3598 VisitForStackValue(expr->right()); | 3594 VisitForStackValue(expr->right()); |
3599 SetExpressionPosition(expr); | 3595 SetExpressionPosition(expr); |
3600 CallRuntimeWithOperands(Runtime::kHasProperty); | 3596 EmitInExpression(); |
3601 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3597 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3602 __ CompareRoot(r2, Heap::kTrueValueRootIndex); | 3598 __ CompareRoot(r2, Heap::kTrueValueRootIndex); |
3603 Split(eq, if_true, if_false, fall_through); | 3599 Split(eq, if_true, if_false, fall_through); |
3604 break; | 3600 break; |
3605 | 3601 |
3606 case Token::INSTANCEOF: { | 3602 case Token::INSTANCEOF: { |
3607 VisitForAccumulatorValue(expr->right()); | 3603 VisitForAccumulatorValue(expr->right()); |
3608 SetExpressionPosition(expr); | 3604 SetExpressionPosition(expr); |
3609 PopOperand(r3); | 3605 PopOperand(r3); |
3610 InstanceOfStub stub(isolate()); | 3606 InstanceOfStub stub(isolate()); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3846 DCHECK(kOSRBranchInstruction == br_instr); | 3842 DCHECK(kOSRBranchInstruction == br_instr); |
3847 | 3843 |
3848 DCHECK(interrupt_address == | 3844 DCHECK(interrupt_address == |
3849 isolate->builtins()->OnStackReplacement()->entry()); | 3845 isolate->builtins()->OnStackReplacement()->entry()); |
3850 return ON_STACK_REPLACEMENT; | 3846 return ON_STACK_REPLACEMENT; |
3851 } | 3847 } |
3852 | 3848 |
3853 } // namespace internal | 3849 } // namespace internal |
3854 } // namespace v8 | 3850 } // namespace v8 |
3855 #endif // V8_TARGET_ARCH_S390 | 3851 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |