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 2058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 __ bind(&l_call); | 2069 __ bind(&l_call); |
2070 __ movp(load_receiver, Operand(rsp, kPointerSize)); | 2070 __ movp(load_receiver, Operand(rsp, kPointerSize)); |
2071 __ Move(LoadDescriptor::SlotRegister(), | 2071 __ Move(LoadDescriptor::SlotRegister(), |
2072 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); | 2072 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); |
2073 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 2073 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
2074 CallIC(ic, TypeFeedbackId::None()); | 2074 CallIC(ic, TypeFeedbackId::None()); |
2075 __ movp(rdi, rax); | 2075 __ movp(rdi, rax); |
2076 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2076 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2077 | 2077 |
2078 SetCallPosition(expr, 1); | 2078 SetCallPosition(expr, 1); |
2079 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2079 __ Set(rax, 1); |
2080 __ CallStub(&stub); | 2080 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2081 | 2081 |
2082 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2082 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2083 __ Drop(1); // The function is still on the stack; drop it. | 2083 __ Drop(1); // The function is still on the stack; drop it. |
2084 | 2084 |
2085 // if (!result.done) goto l_try; | 2085 // if (!result.done) goto l_try; |
2086 __ bind(&l_loop); | 2086 __ bind(&l_loop); |
2087 __ Move(load_receiver, rax); | 2087 __ Move(load_receiver, rax); |
2088 __ Push(load_receiver); // save result | 2088 __ Push(load_receiver); // save result |
2089 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2089 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
2090 __ Move(LoadDescriptor::SlotRegister(), | 2090 __ Move(LoadDescriptor::SlotRegister(), |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2701 TypeFeedbackId ast_id) { | 2701 TypeFeedbackId ast_id) { |
2702 ic_total_count_++; | 2702 ic_total_count_++; |
2703 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2703 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2704 } | 2704 } |
2705 | 2705 |
2706 | 2706 |
2707 // Code common for calls using the IC. | 2707 // Code common for calls using the IC. |
2708 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2708 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2709 Expression* callee = expr->expression(); | 2709 Expression* callee = expr->expression(); |
2710 | 2710 |
2711 CallICState::CallType call_type = | |
2712 callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD; | |
2713 // Get the target function. | 2711 // Get the target function. |
2714 if (call_type == CallICState::FUNCTION) { | 2712 if (callee->IsVariableProxy()) { |
2715 { StackValueContext context(this); | 2713 { StackValueContext context(this); |
2716 EmitVariableLoad(callee->AsVariableProxy()); | 2714 EmitVariableLoad(callee->AsVariableProxy()); |
2717 PrepareForBailout(callee, NO_REGISTERS); | 2715 PrepareForBailout(callee, NO_REGISTERS); |
2718 } | 2716 } |
2719 // Push undefined as receiver. This is patched in the method prologue if it | 2717 // Push undefined as receiver. This is patched in the method prologue if it |
2720 // is a sloppy mode method. | 2718 // is a sloppy mode method. |
2721 __ Push(isolate()->factory()->undefined_value()); | 2719 __ Push(isolate()->factory()->undefined_value()); |
2722 } else { | 2720 } else { |
2723 // Load the function from the receiver. | 2721 // Load the function from the receiver. |
2724 DCHECK(callee->IsProperty()); | 2722 DCHECK(callee->IsProperty()); |
2725 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2723 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2726 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 2724 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
2727 EmitNamedPropertyLoad(callee->AsProperty()); | 2725 EmitNamedPropertyLoad(callee->AsProperty()); |
2728 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2726 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2729 // Push the target function under the receiver. | 2727 // Push the target function under the receiver. |
2730 __ Push(Operand(rsp, 0)); | 2728 __ Push(Operand(rsp, 0)); |
2731 __ movp(Operand(rsp, kPointerSize), rax); | 2729 __ movp(Operand(rsp, kPointerSize), rax); |
2732 } | 2730 } |
2733 | 2731 |
2734 EmitCall(expr, call_type); | 2732 EmitCall(expr); |
2735 } | 2733 } |
2736 | 2734 |
2737 | 2735 |
2738 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2736 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2739 Expression* callee = expr->expression(); | 2737 Expression* callee = expr->expression(); |
2740 DCHECK(callee->IsProperty()); | 2738 DCHECK(callee->IsProperty()); |
2741 Property* prop = callee->AsProperty(); | 2739 Property* prop = callee->AsProperty(); |
2742 DCHECK(prop->IsSuperAccess()); | 2740 DCHECK(prop->IsSuperAccess()); |
2743 SetExpressionPosition(prop); | 2741 SetExpressionPosition(prop); |
2744 | 2742 |
(...skipping 17 matching lines...) Expand all Loading... |
2762 // - key | 2760 // - key |
2763 // - language_mode | 2761 // - language_mode |
2764 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2762 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
2765 | 2763 |
2766 // Replace home_object with target function. | 2764 // Replace home_object with target function. |
2767 __ movp(Operand(rsp, kPointerSize), rax); | 2765 __ movp(Operand(rsp, kPointerSize), rax); |
2768 | 2766 |
2769 // Stack here: | 2767 // Stack here: |
2770 // - target function | 2768 // - target function |
2771 // - this (receiver) | 2769 // - this (receiver) |
2772 EmitCall(expr, CallICState::METHOD); | 2770 EmitCall(expr); |
2773 } | 2771 } |
2774 | 2772 |
2775 | 2773 |
2776 // Common code for calls using the IC. | 2774 // Common code for calls using the IC. |
2777 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2775 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2778 Expression* key) { | 2776 Expression* key) { |
2779 // Load the key. | 2777 // Load the key. |
2780 VisitForAccumulatorValue(key); | 2778 VisitForAccumulatorValue(key); |
2781 | 2779 |
2782 Expression* callee = expr->expression(); | 2780 Expression* callee = expr->expression(); |
2783 | 2781 |
2784 // Load the function from the receiver. | 2782 // Load the function from the receiver. |
2785 DCHECK(callee->IsProperty()); | 2783 DCHECK(callee->IsProperty()); |
2786 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 2784 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
2787 __ Move(LoadDescriptor::NameRegister(), rax); | 2785 __ Move(LoadDescriptor::NameRegister(), rax); |
2788 EmitKeyedPropertyLoad(callee->AsProperty()); | 2786 EmitKeyedPropertyLoad(callee->AsProperty()); |
2789 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2787 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2790 | 2788 |
2791 // Push the target function under the receiver. | 2789 // Push the target function under the receiver. |
2792 __ Push(Operand(rsp, 0)); | 2790 __ Push(Operand(rsp, 0)); |
2793 __ movp(Operand(rsp, kPointerSize), rax); | 2791 __ movp(Operand(rsp, kPointerSize), rax); |
2794 | 2792 |
2795 EmitCall(expr, CallICState::METHOD); | 2793 EmitCall(expr); |
2796 } | 2794 } |
2797 | 2795 |
2798 | 2796 |
2799 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2797 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2800 Expression* callee = expr->expression(); | 2798 Expression* callee = expr->expression(); |
2801 DCHECK(callee->IsProperty()); | 2799 DCHECK(callee->IsProperty()); |
2802 Property* prop = callee->AsProperty(); | 2800 Property* prop = callee->AsProperty(); |
2803 DCHECK(prop->IsSuperAccess()); | 2801 DCHECK(prop->IsSuperAccess()); |
2804 | 2802 |
2805 SetExpressionPosition(prop); | 2803 SetExpressionPosition(prop); |
(...skipping 15 matching lines...) Expand all Loading... |
2821 // - key | 2819 // - key |
2822 // - language_mode | 2820 // - language_mode |
2823 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2821 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
2824 | 2822 |
2825 // Replace home_object with target function. | 2823 // Replace home_object with target function. |
2826 __ movp(Operand(rsp, kPointerSize), rax); | 2824 __ movp(Operand(rsp, kPointerSize), rax); |
2827 | 2825 |
2828 // Stack here: | 2826 // Stack here: |
2829 // - target function | 2827 // - target function |
2830 // - this (receiver) | 2828 // - this (receiver) |
2831 EmitCall(expr, CallICState::METHOD); | 2829 EmitCall(expr); |
2832 } | 2830 } |
2833 | 2831 |
2834 | 2832 |
2835 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2833 void FullCodeGenerator::EmitCall(Call* expr) { |
2836 // Load the arguments. | 2834 // Load the arguments. |
2837 ZoneList<Expression*>* args = expr->arguments(); | 2835 ZoneList<Expression*>* args = expr->arguments(); |
2838 int arg_count = args->length(); | 2836 int arg_count = args->length(); |
2839 for (int i = 0; i < arg_count; i++) { | 2837 for (int i = 0; i < arg_count; i++) { |
2840 VisitForStackValue(args->at(i)); | 2838 VisitForStackValue(args->at(i)); |
2841 } | 2839 } |
2842 | 2840 |
2843 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2841 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2844 SetCallPosition(expr, arg_count); | 2842 SetCallPosition(expr, arg_count); |
2845 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2843 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code(); |
2846 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | 2844 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); |
2847 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2845 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2848 // Don't assign a type feedback id to the IC, since type feedback is provided | 2846 // Don't assign a type feedback id to the IC, since type feedback is provided |
2849 // by the vector above. | 2847 // by the vector above. |
2850 CallIC(ic); | 2848 CallIC(ic); |
2851 | 2849 |
2852 RecordJSReturnSite(expr); | 2850 RecordJSReturnSite(expr); |
2853 | 2851 |
2854 // Restore context register. | 2852 // Restore context register. |
2855 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2853 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 // eval. | 2936 // eval. |
2939 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); | 2937 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); |
2940 EmitResolvePossiblyDirectEval(arg_count); | 2938 EmitResolvePossiblyDirectEval(arg_count); |
2941 | 2939 |
2942 // Touch up the callee. | 2940 // Touch up the callee. |
2943 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); | 2941 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); |
2944 | 2942 |
2945 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2943 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2946 | 2944 |
2947 SetCallPosition(expr, arg_count); | 2945 SetCallPosition(expr, arg_count); |
2948 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
2949 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2946 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2950 __ CallStub(&stub); | 2947 __ Set(rax, arg_count); |
| 2948 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2951 RecordJSReturnSite(expr); | 2949 RecordJSReturnSite(expr); |
2952 // Restore context register. | 2950 // Restore context register. |
2953 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2951 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2954 context()->DropAndPlug(1, rax); | 2952 context()->DropAndPlug(1, rax); |
2955 } | 2953 } |
2956 | 2954 |
2957 | 2955 |
2958 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2956 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2959 Comment cmnt(masm_, "[ CallNew"); | 2957 Comment cmnt(masm_, "[ CallNew"); |
2960 // According to ECMA-262, section 11.2.2, page 44, the function | 2958 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4219 __ movp(rax, FieldOperand(rax, JSGlobalObject::kNativeContextOffset)); | 4217 __ movp(rax, FieldOperand(rax, JSGlobalObject::kNativeContextOffset)); |
4220 __ movp(rax, ContextOperand(rax, expr->context_index())); | 4218 __ movp(rax, ContextOperand(rax, expr->context_index())); |
4221 } | 4219 } |
4222 | 4220 |
4223 | 4221 |
4224 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4222 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4225 ZoneList<Expression*>* args = expr->arguments(); | 4223 ZoneList<Expression*>* args = expr->arguments(); |
4226 int arg_count = args->length(); | 4224 int arg_count = args->length(); |
4227 | 4225 |
4228 SetCallPosition(expr, arg_count); | 4226 SetCallPosition(expr, arg_count); |
4229 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
4230 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 4227 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
4231 __ CallStub(&stub); | 4228 __ Set(rax, arg_count); |
| 4229 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
4232 } | 4230 } |
4233 | 4231 |
4234 | 4232 |
4235 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4233 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4236 ZoneList<Expression*>* args = expr->arguments(); | 4234 ZoneList<Expression*>* args = expr->arguments(); |
4237 int arg_count = args->length(); | 4235 int arg_count = args->length(); |
4238 | 4236 |
4239 if (expr->is_jsruntime()) { | 4237 if (expr->is_jsruntime()) { |
4240 Comment cmnt(masm_, "[ CallRuntime"); | 4238 Comment cmnt(masm_, "[ CallRuntime"); |
4241 | 4239 |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5030 Assembler::target_address_at(call_target_address, | 5028 Assembler::target_address_at(call_target_address, |
5031 unoptimized_code)); | 5029 unoptimized_code)); |
5032 return OSR_AFTER_STACK_CHECK; | 5030 return OSR_AFTER_STACK_CHECK; |
5033 } | 5031 } |
5034 | 5032 |
5035 | 5033 |
5036 } // namespace internal | 5034 } // namespace internal |
5037 } // namespace v8 | 5035 } // namespace v8 |
5038 | 5036 |
5039 #endif // V8_TARGET_ARCH_X64 | 5037 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |