OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 __ movp(load_receiver, Operand(rsp, kPointerSize)); | 2058 __ movp(load_receiver, Operand(rsp, kPointerSize)); |
2059 __ Move(LoadDescriptor::SlotRegister(), | 2059 __ Move(LoadDescriptor::SlotRegister(), |
2060 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); | 2060 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); |
2061 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 2061 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
2062 CallIC(ic, TypeFeedbackId::None()); | 2062 CallIC(ic, TypeFeedbackId::None()); |
2063 __ movp(rdi, rax); | 2063 __ movp(rdi, rax); |
2064 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2064 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2065 | 2065 |
2066 SetCallPosition(expr, 1); | 2066 SetCallPosition(expr, 1); |
2067 __ Set(rax, 1); | 2067 __ Set(rax, 1); |
2068 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2068 __ Call( |
| 2069 isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), |
| 2070 RelocInfo::CODE_TARGET); |
2069 | 2071 |
2070 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2072 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2071 __ Drop(1); // The function is still on the stack; drop it. | 2073 __ Drop(1); // The function is still on the stack; drop it. |
2072 | 2074 |
2073 // if (!result.done) goto l_try; | 2075 // if (!result.done) goto l_try; |
2074 __ bind(&l_loop); | 2076 __ bind(&l_loop); |
2075 __ Move(load_receiver, rax); | 2077 __ Move(load_receiver, rax); |
2076 __ Push(load_receiver); // save result | 2078 __ Push(load_receiver); // save result |
2077 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2079 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
2078 __ Move(LoadDescriptor::SlotRegister(), | 2080 __ Move(LoadDescriptor::SlotRegister(), |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2690 ic_total_count_++; | 2692 ic_total_count_++; |
2691 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2693 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2692 } | 2694 } |
2693 | 2695 |
2694 | 2696 |
2695 // Code common for calls using the IC. | 2697 // Code common for calls using the IC. |
2696 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2698 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2697 Expression* callee = expr->expression(); | 2699 Expression* callee = expr->expression(); |
2698 | 2700 |
2699 // Get the target function. | 2701 // Get the target function. |
| 2702 ConvertReceiverMode convert_mode; |
2700 if (callee->IsVariableProxy()) { | 2703 if (callee->IsVariableProxy()) { |
2701 { StackValueContext context(this); | 2704 { StackValueContext context(this); |
2702 EmitVariableLoad(callee->AsVariableProxy()); | 2705 EmitVariableLoad(callee->AsVariableProxy()); |
2703 PrepareForBailout(callee, NO_REGISTERS); | 2706 PrepareForBailout(callee, NO_REGISTERS); |
2704 } | 2707 } |
2705 // Push undefined as receiver. This is patched in the method prologue if it | 2708 // Push undefined as receiver. This is patched in the Call builtin if it |
2706 // is a sloppy mode method. | 2709 // is a sloppy mode method. |
2707 __ Push(isolate()->factory()->undefined_value()); | 2710 __ Push(isolate()->factory()->undefined_value()); |
| 2711 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2708 } else { | 2712 } else { |
2709 // Load the function from the receiver. | 2713 // Load the function from the receiver. |
2710 DCHECK(callee->IsProperty()); | 2714 DCHECK(callee->IsProperty()); |
2711 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2715 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2712 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 2716 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
2713 EmitNamedPropertyLoad(callee->AsProperty()); | 2717 EmitNamedPropertyLoad(callee->AsProperty()); |
2714 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2718 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2715 // Push the target function under the receiver. | 2719 // Push the target function under the receiver. |
2716 __ Push(Operand(rsp, 0)); | 2720 __ Push(Operand(rsp, 0)); |
2717 __ movp(Operand(rsp, kPointerSize), rax); | 2721 __ movp(Operand(rsp, kPointerSize), rax); |
| 2722 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2718 } | 2723 } |
2719 | 2724 |
2720 EmitCall(expr); | 2725 EmitCall(expr, convert_mode); |
2721 } | 2726 } |
2722 | 2727 |
2723 | 2728 |
2724 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2729 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2725 Expression* callee = expr->expression(); | 2730 Expression* callee = expr->expression(); |
2726 DCHECK(callee->IsProperty()); | 2731 DCHECK(callee->IsProperty()); |
2727 Property* prop = callee->AsProperty(); | 2732 Property* prop = callee->AsProperty(); |
2728 DCHECK(prop->IsSuperAccess()); | 2733 DCHECK(prop->IsSuperAccess()); |
2729 SetExpressionPosition(prop); | 2734 SetExpressionPosition(prop); |
2730 | 2735 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2771 DCHECK(callee->IsProperty()); | 2776 DCHECK(callee->IsProperty()); |
2772 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 2777 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
2773 __ Move(LoadDescriptor::NameRegister(), rax); | 2778 __ Move(LoadDescriptor::NameRegister(), rax); |
2774 EmitKeyedPropertyLoad(callee->AsProperty()); | 2779 EmitKeyedPropertyLoad(callee->AsProperty()); |
2775 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2780 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2776 | 2781 |
2777 // Push the target function under the receiver. | 2782 // Push the target function under the receiver. |
2778 __ Push(Operand(rsp, 0)); | 2783 __ Push(Operand(rsp, 0)); |
2779 __ movp(Operand(rsp, kPointerSize), rax); | 2784 __ movp(Operand(rsp, kPointerSize), rax); |
2780 | 2785 |
2781 EmitCall(expr); | 2786 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2782 } | 2787 } |
2783 | 2788 |
2784 | 2789 |
2785 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2790 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2786 Expression* callee = expr->expression(); | 2791 Expression* callee = expr->expression(); |
2787 DCHECK(callee->IsProperty()); | 2792 DCHECK(callee->IsProperty()); |
2788 Property* prop = callee->AsProperty(); | 2793 Property* prop = callee->AsProperty(); |
2789 DCHECK(prop->IsSuperAccess()); | 2794 DCHECK(prop->IsSuperAccess()); |
2790 | 2795 |
2791 SetExpressionPosition(prop); | 2796 SetExpressionPosition(prop); |
(...skipping 19 matching lines...) Expand all Loading... |
2811 // Replace home_object with target function. | 2816 // Replace home_object with target function. |
2812 __ movp(Operand(rsp, kPointerSize), rax); | 2817 __ movp(Operand(rsp, kPointerSize), rax); |
2813 | 2818 |
2814 // Stack here: | 2819 // Stack here: |
2815 // - target function | 2820 // - target function |
2816 // - this (receiver) | 2821 // - this (receiver) |
2817 EmitCall(expr); | 2822 EmitCall(expr); |
2818 } | 2823 } |
2819 | 2824 |
2820 | 2825 |
2821 void FullCodeGenerator::EmitCall(Call* expr) { | 2826 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
2822 // Load the arguments. | 2827 // Load the arguments. |
2823 ZoneList<Expression*>* args = expr->arguments(); | 2828 ZoneList<Expression*>* args = expr->arguments(); |
2824 int arg_count = args->length(); | 2829 int arg_count = args->length(); |
2825 for (int i = 0; i < arg_count; i++) { | 2830 for (int i = 0; i < arg_count; i++) { |
2826 VisitForStackValue(args->at(i)); | 2831 VisitForStackValue(args->at(i)); |
2827 } | 2832 } |
2828 | 2833 |
2829 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2834 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2830 SetCallPosition(expr, arg_count); | 2835 SetCallPosition(expr, arg_count); |
2831 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code(); | 2836 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, mode).code(); |
2832 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | 2837 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); |
2833 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2838 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2834 // Don't assign a type feedback id to the IC, since type feedback is provided | 2839 // Don't assign a type feedback id to the IC, since type feedback is provided |
2835 // by the vector above. | 2840 // by the vector above. |
2836 CallIC(ic); | 2841 CallIC(ic); |
2837 | 2842 |
2838 RecordJSReturnSite(expr); | 2843 RecordJSReturnSite(expr); |
2839 | 2844 |
2840 // Restore context register. | 2845 // Restore context register. |
2841 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2846 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4161 } | 4166 } |
4162 | 4167 |
4163 | 4168 |
4164 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4169 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4165 ZoneList<Expression*>* args = expr->arguments(); | 4170 ZoneList<Expression*>* args = expr->arguments(); |
4166 int arg_count = args->length(); | 4171 int arg_count = args->length(); |
4167 | 4172 |
4168 SetCallPosition(expr, arg_count); | 4173 SetCallPosition(expr, arg_count); |
4169 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 4174 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
4170 __ Set(rax, arg_count); | 4175 __ Set(rax, arg_count); |
4171 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 4176 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 4177 RelocInfo::CODE_TARGET); |
4172 } | 4178 } |
4173 | 4179 |
4174 | 4180 |
4175 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4181 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4176 ZoneList<Expression*>* args = expr->arguments(); | 4182 ZoneList<Expression*>* args = expr->arguments(); |
4177 int arg_count = args->length(); | 4183 int arg_count = args->length(); |
4178 | 4184 |
4179 if (expr->is_jsruntime()) { | 4185 if (expr->is_jsruntime()) { |
4180 Comment cmnt(masm_, "[ CallRuntime"); | 4186 Comment cmnt(masm_, "[ CallRuntime"); |
4181 | 4187 |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4970 Assembler::target_address_at(call_target_address, | 4976 Assembler::target_address_at(call_target_address, |
4971 unoptimized_code)); | 4977 unoptimized_code)); |
4972 return OSR_AFTER_STACK_CHECK; | 4978 return OSR_AFTER_STACK_CHECK; |
4973 } | 4979 } |
4974 | 4980 |
4975 | 4981 |
4976 } // namespace internal | 4982 } // namespace internal |
4977 } // namespace v8 | 4983 } // namespace v8 |
4978 | 4984 |
4979 #endif // V8_TARGET_ARCH_X64 | 4985 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |