OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 // arguments, consider how to improve it without creating a security | 453 // arguments, consider how to improve it without creating a security |
454 // hole. | 454 // hole. |
455 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); | 455 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); |
456 __ Add(current_sp, current_sp, ip0); | 456 __ Add(current_sp, current_sp, ip0); |
457 __ Ret(); | 457 __ Ret(); |
458 int32_t arg_count = info_->scope()->num_parameters() + 1; | 458 int32_t arg_count = info_->scope()->num_parameters() + 1; |
459 __ dc64(kXRegSize * arg_count); | 459 __ dc64(kXRegSize * arg_count); |
460 } | 460 } |
461 } | 461 } |
462 | 462 |
| 463 void FullCodeGenerator::RestoreContext() { |
| 464 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 465 } |
463 | 466 |
464 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 467 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
465 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 468 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
466 codegen()->GetVar(result_register(), var); | 469 codegen()->GetVar(result_register(), var); |
467 codegen()->PushOperand(result_register()); | 470 codegen()->PushOperand(result_register()); |
468 } | 471 } |
469 | 472 |
470 | 473 |
471 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 474 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
472 // Root values have no side effects. | 475 // Root values have no side effects. |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 __ Mov(x2, Smi::FromInt(expr->literal_index())); | 1400 __ Mov(x2, Smi::FromInt(expr->literal_index())); |
1398 __ Mov(x1, Operand(constant_properties)); | 1401 __ Mov(x1, Operand(constant_properties)); |
1399 int flags = expr->ComputeFlags(); | 1402 int flags = expr->ComputeFlags(); |
1400 __ Mov(x0, Smi::FromInt(flags)); | 1403 __ Mov(x0, Smi::FromInt(flags)); |
1401 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1404 if (MustCreateObjectLiteralWithRuntime(expr)) { |
1402 __ Push(x3, x2, x1, x0); | 1405 __ Push(x3, x2, x1, x0); |
1403 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1406 __ CallRuntime(Runtime::kCreateObjectLiteral); |
1404 } else { | 1407 } else { |
1405 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1408 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1406 __ CallStub(&stub); | 1409 __ CallStub(&stub); |
1407 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1410 RestoreContext(); |
1408 } | 1411 } |
1409 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1412 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1410 | 1413 |
1411 // If result_saved is true the result is on top of the stack. If | 1414 // If result_saved is true the result is on top of the stack. If |
1412 // result_saved is false the result is in x0. | 1415 // result_saved is false the result is in x0. |
1413 bool result_saved = false; | 1416 bool result_saved = false; |
1414 | 1417 |
1415 AccessorTable accessor_table(zone()); | 1418 AccessorTable accessor_table(zone()); |
1416 int property_index = 0; | 1419 int property_index = 0; |
1417 for (; property_index < expr->properties()->length(); property_index++) { | 1420 for (; property_index < expr->properties()->length(); property_index++) { |
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2424 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2422 .code(); | 2425 .code(); |
2423 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2426 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
2424 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2427 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2425 // Don't assign a type feedback id to the IC, since type feedback is provided | 2428 // Don't assign a type feedback id to the IC, since type feedback is provided |
2426 // by the vector above. | 2429 // by the vector above. |
2427 CallIC(ic); | 2430 CallIC(ic); |
2428 OperandStackDepthDecrement(arg_count + 1); | 2431 OperandStackDepthDecrement(arg_count + 1); |
2429 | 2432 |
2430 RecordJSReturnSite(expr); | 2433 RecordJSReturnSite(expr); |
2431 // Restore context register. | 2434 RestoreContext(); |
2432 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2433 context()->DropAndPlug(1, x0); | 2435 context()->DropAndPlug(1, x0); |
2434 } | 2436 } |
2435 | 2437 |
2436 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2438 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
2437 int arg_count = expr->arguments()->length(); | 2439 int arg_count = expr->arguments()->length(); |
2438 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); | 2440 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); |
2439 // Prepare to push a copy of the first argument or undefined if it doesn't | 2441 // Prepare to push a copy of the first argument or undefined if it doesn't |
2440 // exist. | 2442 // exist. |
2441 if (arg_count > 0) { | 2443 if (arg_count > 0) { |
2442 __ Peek(x9, arg_count * kXRegSize); | 2444 __ Peek(x9, arg_count * kXRegSize); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2532 SetCallPosition(expr); | 2534 SetCallPosition(expr); |
2533 | 2535 |
2534 // Call the evaluated function. | 2536 // Call the evaluated function. |
2535 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2537 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2536 __ Mov(x0, arg_count); | 2538 __ Mov(x0, arg_count); |
2537 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2539 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2538 expr->tail_call_mode()), | 2540 expr->tail_call_mode()), |
2539 RelocInfo::CODE_TARGET); | 2541 RelocInfo::CODE_TARGET); |
2540 OperandStackDepthDecrement(arg_count + 1); | 2542 OperandStackDepthDecrement(arg_count + 1); |
2541 RecordJSReturnSite(expr); | 2543 RecordJSReturnSite(expr); |
2542 // Restore context register. | 2544 RestoreContext(); |
2543 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2544 context()->DropAndPlug(1, x0); | 2545 context()->DropAndPlug(1, x0); |
2545 } | 2546 } |
2546 | 2547 |
2547 | 2548 |
2548 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2549 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2549 Comment cmnt(masm_, "[ CallNew"); | 2550 Comment cmnt(masm_, "[ CallNew"); |
2550 // According to ECMA-262, section 11.2.2, page 44, the function | 2551 // According to ECMA-262, section 11.2.2, page 44, the function |
2551 // expression in new calls must be evaluated before the | 2552 // expression in new calls must be evaluated before the |
2552 // arguments. | 2553 // arguments. |
2553 | 2554 |
(...skipping 19 matching lines...) Expand all Loading... |
2573 __ Peek(x1, arg_count * kXRegSize); | 2574 __ Peek(x1, arg_count * kXRegSize); |
2574 | 2575 |
2575 // Record call targets in unoptimized code. | 2576 // Record call targets in unoptimized code. |
2576 __ EmitLoadTypeFeedbackVector(x2); | 2577 __ EmitLoadTypeFeedbackVector(x2); |
2577 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2578 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); |
2578 | 2579 |
2579 CallConstructStub stub(isolate()); | 2580 CallConstructStub stub(isolate()); |
2580 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2581 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
2581 OperandStackDepthDecrement(arg_count + 1); | 2582 OperandStackDepthDecrement(arg_count + 1); |
2582 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2583 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2583 // Restore context register. | 2584 RestoreContext(); |
2584 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2585 context()->Plug(x0); | 2585 context()->Plug(x0); |
2586 } | 2586 } |
2587 | 2587 |
2588 | 2588 |
2589 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2589 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2590 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); | 2590 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); |
2591 SuperCallReference* super_call_ref = | 2591 SuperCallReference* super_call_ref = |
2592 expr->expression()->AsSuperCallReference(); | 2592 expr->expression()->AsSuperCallReference(); |
2593 DCHECK_NOT_NULL(super_call_ref); | 2593 DCHECK_NOT_NULL(super_call_ref); |
2594 | 2594 |
(...skipping 23 matching lines...) Expand all Loading... |
2618 __ Mov(x3, result_register()); | 2618 __ Mov(x3, result_register()); |
2619 | 2619 |
2620 // Load function and argument count into x1 and x0. | 2620 // Load function and argument count into x1 and x0. |
2621 __ Mov(x0, arg_count); | 2621 __ Mov(x0, arg_count); |
2622 __ Peek(x1, arg_count * kXRegSize); | 2622 __ Peek(x1, arg_count * kXRegSize); |
2623 | 2623 |
2624 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2624 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2625 OperandStackDepthDecrement(arg_count + 1); | 2625 OperandStackDepthDecrement(arg_count + 1); |
2626 | 2626 |
2627 RecordJSReturnSite(expr); | 2627 RecordJSReturnSite(expr); |
2628 | 2628 RestoreContext(); |
2629 // Restore context register. | |
2630 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2631 context()->Plug(x0); | 2629 context()->Plug(x0); |
2632 } | 2630 } |
2633 | 2631 |
2634 | 2632 |
2635 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2633 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2636 ZoneList<Expression*>* args = expr->arguments(); | 2634 ZoneList<Expression*>* args = expr->arguments(); |
2637 DCHECK(args->length() == 1); | 2635 DCHECK(args->length() == 1); |
2638 | 2636 |
2639 VisitForAccumulatorValue(args->at(0)); | 2637 VisitForAccumulatorValue(args->at(0)); |
2640 | 2638 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3016 VisitForStackValue(arg); | 3014 VisitForStackValue(arg); |
3017 } | 3015 } |
3018 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3016 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3019 // Move target to x1. | 3017 // Move target to x1. |
3020 int const argc = args->length() - 2; | 3018 int const argc = args->length() - 2; |
3021 __ Peek(x1, (argc + 1) * kXRegSize); | 3019 __ Peek(x1, (argc + 1) * kXRegSize); |
3022 // Call the target. | 3020 // Call the target. |
3023 __ Mov(x0, argc); | 3021 __ Mov(x0, argc); |
3024 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3022 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3025 OperandStackDepthDecrement(argc + 1); | 3023 OperandStackDepthDecrement(argc + 1); |
3026 // Restore context register. | 3024 RestoreContext(); |
3027 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3028 // Discard the function left on TOS. | 3025 // Discard the function left on TOS. |
3029 context()->DropAndPlug(1, x0); | 3026 context()->DropAndPlug(1, x0); |
3030 } | 3027 } |
3031 | 3028 |
3032 | 3029 |
3033 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3030 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3034 ZoneList<Expression*>* args = expr->arguments(); | 3031 ZoneList<Expression*>* args = expr->arguments(); |
3035 VisitForAccumulatorValue(args->at(0)); | 3032 VisitForAccumulatorValue(args->at(0)); |
3036 | 3033 |
3037 Label materialize_true, materialize_false; | 3034 Label materialize_true, materialize_false; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3145 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3142 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3146 ZoneList<Expression*>* args = expr->arguments(); | 3143 ZoneList<Expression*>* args = expr->arguments(); |
3147 int arg_count = args->length(); | 3144 int arg_count = args->length(); |
3148 | 3145 |
3149 SetCallPosition(expr); | 3146 SetCallPosition(expr); |
3150 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3147 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3151 __ Mov(x0, arg_count); | 3148 __ Mov(x0, arg_count); |
3152 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3149 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3153 RelocInfo::CODE_TARGET); | 3150 RelocInfo::CODE_TARGET); |
3154 OperandStackDepthDecrement(arg_count + 1); | 3151 OperandStackDepthDecrement(arg_count + 1); |
3155 | 3152 RestoreContext(); |
3156 // Restore context register. | |
3157 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3158 } | 3153 } |
3159 | 3154 |
3160 | 3155 |
3161 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3156 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3162 switch (expr->op()) { | 3157 switch (expr->op()) { |
3163 case Token::DELETE: { | 3158 case Token::DELETE: { |
3164 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3159 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3165 Property* property = expr->expression()->AsProperty(); | 3160 Property* property = expr->expression()->AsProperty(); |
3166 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3161 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3167 | 3162 |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3620 Label* fall_through = NULL; | 3615 Label* fall_through = NULL; |
3621 context()->PrepareTest(&materialize_true, &materialize_false, | 3616 context()->PrepareTest(&materialize_true, &materialize_false, |
3622 &if_true, &if_false, &fall_through); | 3617 &if_true, &if_false, &fall_through); |
3623 | 3618 |
3624 Token::Value op = expr->op(); | 3619 Token::Value op = expr->op(); |
3625 VisitForStackValue(expr->left()); | 3620 VisitForStackValue(expr->left()); |
3626 switch (op) { | 3621 switch (op) { |
3627 case Token::IN: | 3622 case Token::IN: |
3628 VisitForStackValue(expr->right()); | 3623 VisitForStackValue(expr->right()); |
3629 SetExpressionPosition(expr); | 3624 SetExpressionPosition(expr); |
3630 CallRuntimeWithOperands(Runtime::kHasProperty); | 3625 EmitHasProperty(); |
3631 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3626 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3632 __ CompareRoot(x0, Heap::kTrueValueRootIndex); | 3627 __ CompareRoot(x0, Heap::kTrueValueRootIndex); |
3633 Split(eq, if_true, if_false, fall_through); | 3628 Split(eq, if_true, if_false, fall_through); |
3634 break; | 3629 break; |
3635 | 3630 |
3636 case Token::INSTANCEOF: { | 3631 case Token::INSTANCEOF: { |
3637 VisitForAccumulatorValue(expr->right()); | 3632 VisitForAccumulatorValue(expr->right()); |
3638 SetExpressionPosition(expr); | 3633 SetExpressionPosition(expr); |
3639 PopOperand(x1); | 3634 PopOperand(x1); |
3640 InstanceOfStub stub(isolate()); | 3635 InstanceOfStub stub(isolate()); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3751 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); | 3746 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); |
3752 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); | 3747 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); |
3753 __ Mov(x1, cp); | 3748 __ Mov(x1, cp); |
3754 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, | 3749 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |
3755 kLRHasBeenSaved, kDontSaveFPRegs); | 3750 kLRHasBeenSaved, kDontSaveFPRegs); |
3756 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); | 3751 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); |
3757 __ Cmp(__ StackPointer(), x1); | 3752 __ Cmp(__ StackPointer(), x1); |
3758 __ B(eq, &post_runtime); | 3753 __ B(eq, &post_runtime); |
3759 __ Push(x0); // generator object | 3754 __ Push(x0); // generator object |
3760 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 3755 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
3761 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3756 RestoreContext(); |
3762 __ Bind(&post_runtime); | 3757 __ Bind(&post_runtime); |
3763 PopOperand(result_register()); | 3758 PopOperand(result_register()); |
3764 EmitReturnSequence(); | 3759 EmitReturnSequence(); |
3765 | 3760 |
3766 __ Bind(&resume); | 3761 __ Bind(&resume); |
3767 context()->Plug(result_register()); | 3762 context()->Plug(result_register()); |
3768 } | 3763 } |
3769 | 3764 |
3770 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 3765 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
3771 OperandStackDepthIncrement(2); | 3766 OperandStackDepthIncrement(2); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4030 } | 4025 } |
4031 | 4026 |
4032 return INTERRUPT; | 4027 return INTERRUPT; |
4033 } | 4028 } |
4034 | 4029 |
4035 | 4030 |
4036 } // namespace internal | 4031 } // namespace internal |
4037 } // namespace v8 | 4032 } // namespace v8 |
4038 | 4033 |
4039 #endif // V8_TARGET_ARCH_ARM64 | 4034 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |