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/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 2492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 // the debugger can patch them correctly. | 2503 // the debugger can patch them correctly. |
2504 __ Call(code, RelocInfo::CODE_TARGET, ast_id); | 2504 __ Call(code, RelocInfo::CODE_TARGET, ast_id); |
2505 } | 2505 } |
2506 | 2506 |
2507 | 2507 |
2508 // Code common for calls using the IC. | 2508 // Code common for calls using the IC. |
2509 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2509 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2510 Expression* callee = expr->expression(); | 2510 Expression* callee = expr->expression(); |
2511 | 2511 |
2512 // Get the target function. | 2512 // Get the target function. |
| 2513 ConvertReceiverMode convert_mode; |
2513 if (callee->IsVariableProxy()) { | 2514 if (callee->IsVariableProxy()) { |
2514 { StackValueContext context(this); | 2515 { StackValueContext context(this); |
2515 EmitVariableLoad(callee->AsVariableProxy()); | 2516 EmitVariableLoad(callee->AsVariableProxy()); |
2516 PrepareForBailout(callee, NO_REGISTERS); | 2517 PrepareForBailout(callee, NO_REGISTERS); |
2517 } | 2518 } |
2518 // Push undefined as receiver. This is patched in the method prologue if it | 2519 // Push undefined as receiver. This is patched in the method prologue if it |
2519 // is a sloppy mode method. | 2520 // is a sloppy mode method. |
2520 { | 2521 { |
2521 UseScratchRegisterScope temps(masm_); | 2522 UseScratchRegisterScope temps(masm_); |
2522 Register temp = temps.AcquireX(); | 2523 Register temp = temps.AcquireX(); |
2523 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); | 2524 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); |
2524 __ Push(temp); | 2525 __ Push(temp); |
2525 } | 2526 } |
| 2527 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2526 } else { | 2528 } else { |
2527 // Load the function from the receiver. | 2529 // Load the function from the receiver. |
2528 DCHECK(callee->IsProperty()); | 2530 DCHECK(callee->IsProperty()); |
2529 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2531 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2530 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2532 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2531 EmitNamedPropertyLoad(callee->AsProperty()); | 2533 EmitNamedPropertyLoad(callee->AsProperty()); |
2532 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2534 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2533 // Push the target function under the receiver. | 2535 // Push the target function under the receiver. |
2534 __ Pop(x10); | 2536 __ Pop(x10); |
2535 __ Push(x0, x10); | 2537 __ Push(x0, x10); |
| 2538 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2536 } | 2539 } |
2537 | 2540 |
2538 EmitCall(expr); | 2541 EmitCall(expr, convert_mode); |
2539 } | 2542 } |
2540 | 2543 |
2541 | 2544 |
2542 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2545 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2543 Expression* callee = expr->expression(); | 2546 Expression* callee = expr->expression(); |
2544 DCHECK(callee->IsProperty()); | 2547 DCHECK(callee->IsProperty()); |
2545 Property* prop = callee->AsProperty(); | 2548 Property* prop = callee->AsProperty(); |
2546 DCHECK(prop->IsSuperAccess()); | 2549 DCHECK(prop->IsSuperAccess()); |
2547 SetExpressionPosition(prop); | 2550 SetExpressionPosition(prop); |
2548 | 2551 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2591 DCHECK(callee->IsProperty()); | 2594 DCHECK(callee->IsProperty()); |
2592 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2595 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2593 __ Move(LoadDescriptor::NameRegister(), x0); | 2596 __ Move(LoadDescriptor::NameRegister(), x0); |
2594 EmitKeyedPropertyLoad(callee->AsProperty()); | 2597 EmitKeyedPropertyLoad(callee->AsProperty()); |
2595 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2598 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2596 | 2599 |
2597 // Push the target function under the receiver. | 2600 // Push the target function under the receiver. |
2598 __ Pop(x10); | 2601 __ Pop(x10); |
2599 __ Push(x0, x10); | 2602 __ Push(x0, x10); |
2600 | 2603 |
2601 EmitCall(expr); | 2604 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2602 } | 2605 } |
2603 | 2606 |
2604 | 2607 |
2605 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2608 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2606 Expression* callee = expr->expression(); | 2609 Expression* callee = expr->expression(); |
2607 DCHECK(callee->IsProperty()); | 2610 DCHECK(callee->IsProperty()); |
2608 Property* prop = callee->AsProperty(); | 2611 Property* prop = callee->AsProperty(); |
2609 DCHECK(prop->IsSuperAccess()); | 2612 DCHECK(prop->IsSuperAccess()); |
2610 SetExpressionPosition(prop); | 2613 SetExpressionPosition(prop); |
2611 | 2614 |
(...skipping 21 matching lines...) Expand all Loading... |
2633 // Replace home_object with target function. | 2636 // Replace home_object with target function. |
2634 __ Poke(x0, kPointerSize); | 2637 __ Poke(x0, kPointerSize); |
2635 | 2638 |
2636 // Stack here: | 2639 // Stack here: |
2637 // - target function | 2640 // - target function |
2638 // - this (receiver) | 2641 // - this (receiver) |
2639 EmitCall(expr); | 2642 EmitCall(expr); |
2640 } | 2643 } |
2641 | 2644 |
2642 | 2645 |
2643 void FullCodeGenerator::EmitCall(Call* expr) { | 2646 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
2644 // Load the arguments. | 2647 // Load the arguments. |
2645 ZoneList<Expression*>* args = expr->arguments(); | 2648 ZoneList<Expression*>* args = expr->arguments(); |
2646 int arg_count = args->length(); | 2649 int arg_count = args->length(); |
2647 for (int i = 0; i < arg_count; i++) { | 2650 for (int i = 0; i < arg_count; i++) { |
2648 VisitForStackValue(args->at(i)); | 2651 VisitForStackValue(args->at(i)); |
2649 } | 2652 } |
2650 | 2653 |
2651 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2654 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2652 SetCallPosition(expr, arg_count); | 2655 SetCallPosition(expr, arg_count); |
2653 | 2656 |
2654 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code(); | 2657 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, mode).code(); |
2655 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2658 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
2656 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2659 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2657 // Don't assign a type feedback id to the IC, since type feedback is provided | 2660 // Don't assign a type feedback id to the IC, since type feedback is provided |
2658 // by the vector above. | 2661 // by the vector above. |
2659 CallIC(ic); | 2662 CallIC(ic); |
2660 | 2663 |
2661 RecordJSReturnSite(expr); | 2664 RecordJSReturnSite(expr); |
2662 // Restore context register. | 2665 // Restore context register. |
2663 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2666 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2664 context()->DropAndPlug(1, x0); | 2667 context()->DropAndPlug(1, x0); |
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3926 } | 3929 } |
3927 | 3930 |
3928 | 3931 |
3929 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3932 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3930 ZoneList<Expression*>* args = expr->arguments(); | 3933 ZoneList<Expression*>* args = expr->arguments(); |
3931 int arg_count = args->length(); | 3934 int arg_count = args->length(); |
3932 | 3935 |
3933 SetCallPosition(expr, arg_count); | 3936 SetCallPosition(expr, arg_count); |
3934 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3937 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3935 __ Mov(x0, arg_count); | 3938 __ Mov(x0, arg_count); |
3936 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3939 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 3940 RelocInfo::CODE_TARGET); |
3937 } | 3941 } |
3938 | 3942 |
3939 | 3943 |
3940 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3944 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
3941 ZoneList<Expression*>* args = expr->arguments(); | 3945 ZoneList<Expression*>* args = expr->arguments(); |
3942 int arg_count = args->length(); | 3946 int arg_count = args->length(); |
3943 | 3947 |
3944 if (expr->is_jsruntime()) { | 3948 if (expr->is_jsruntime()) { |
3945 Comment cmnt(masm_, "[ CallRunTime"); | 3949 Comment cmnt(masm_, "[ CallRunTime"); |
3946 EmitLoadJSRuntimeFunction(expr); | 3950 EmitLoadJSRuntimeFunction(expr); |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4693 __ Peek(load_receiver, 1 * kPointerSize); | 4697 __ Peek(load_receiver, 1 * kPointerSize); |
4694 __ Peek(load_name, 2 * kPointerSize); | 4698 __ Peek(load_name, 2 * kPointerSize); |
4695 __ Mov(LoadDescriptor::SlotRegister(), | 4699 __ Mov(LoadDescriptor::SlotRegister(), |
4696 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); | 4700 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); |
4697 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 4701 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
4698 CallIC(ic, TypeFeedbackId::None()); | 4702 CallIC(ic, TypeFeedbackId::None()); |
4699 __ Mov(x1, x0); | 4703 __ Mov(x1, x0); |
4700 __ Poke(x1, 2 * kPointerSize); | 4704 __ Poke(x1, 2 * kPointerSize); |
4701 SetCallPosition(expr, 1); | 4705 SetCallPosition(expr, 1); |
4702 __ Mov(x0, 1); | 4706 __ Mov(x0, 1); |
4703 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 4707 __ Call( |
| 4708 isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), |
| 4709 RelocInfo::CODE_TARGET); |
4704 | 4710 |
4705 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4711 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4706 __ Drop(1); // The function is still on the stack; drop it. | 4712 __ Drop(1); // The function is still on the stack; drop it. |
4707 | 4713 |
4708 // if (!result.done) goto l_try; | 4714 // if (!result.done) goto l_try; |
4709 __ Bind(&l_loop); | 4715 __ Bind(&l_loop); |
4710 __ Move(load_receiver, x0); | 4716 __ Move(load_receiver, x0); |
4711 | 4717 |
4712 __ Push(load_receiver); // save result | 4718 __ Push(load_receiver); // save result |
4713 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 4719 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5072 } | 5078 } |
5073 | 5079 |
5074 return INTERRUPT; | 5080 return INTERRUPT; |
5075 } | 5081 } |
5076 | 5082 |
5077 | 5083 |
5078 } // namespace internal | 5084 } // namespace internal |
5079 } // namespace v8 | 5085 } // namespace v8 |
5080 | 5086 |
5081 #endif // V8_TARGET_ARCH_ARM64 | 5087 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |