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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
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 2019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 __ bind(&l_call); | 2030 __ bind(&l_call); |
2031 __ mov(load_receiver, Operand(esp, kPointerSize)); | 2031 __ mov(load_receiver, Operand(esp, kPointerSize)); |
2032 __ mov(LoadDescriptor::SlotRegister(), | 2032 __ mov(LoadDescriptor::SlotRegister(), |
2033 Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot()))); | 2033 Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot()))); |
2034 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 2034 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
2035 CallIC(ic, TypeFeedbackId::None()); | 2035 CallIC(ic, TypeFeedbackId::None()); |
2036 __ mov(edi, eax); | 2036 __ mov(edi, eax); |
2037 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2037 __ mov(Operand(esp, 2 * kPointerSize), edi); |
2038 SetCallPosition(expr, 1); | 2038 SetCallPosition(expr, 1); |
2039 __ Set(eax, 1); | 2039 __ Set(eax, 1); |
2040 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2040 __ Call( |
| 2041 isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), |
| 2042 RelocInfo::CODE_TARGET); |
2041 | 2043 |
2042 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2044 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2043 __ Drop(1); // The function is still on the stack; drop it. | 2045 __ Drop(1); // The function is still on the stack; drop it. |
2044 | 2046 |
2045 // if (!result.done) goto l_try; | 2047 // if (!result.done) goto l_try; |
2046 __ bind(&l_loop); | 2048 __ bind(&l_loop); |
2047 __ push(eax); // save result | 2049 __ push(eax); // save result |
2048 __ Move(load_receiver, eax); // result | 2050 __ Move(load_receiver, eax); // result |
2049 __ mov(load_name, | 2051 __ mov(load_name, |
2050 isolate()->factory()->done_string()); // "done" | 2052 isolate()->factory()->done_string()); // "done" |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2700 ic_total_count_++; | 2702 ic_total_count_++; |
2701 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2703 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2702 } | 2704 } |
2703 | 2705 |
2704 | 2706 |
2705 // Code common for calls using the IC. | 2707 // Code common for calls using the IC. |
2706 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2708 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2707 Expression* callee = expr->expression(); | 2709 Expression* callee = expr->expression(); |
2708 | 2710 |
2709 // Get the target function. | 2711 // Get the target function. |
| 2712 ConvertReceiverMode convert_mode; |
2710 if (callee->IsVariableProxy()) { | 2713 if (callee->IsVariableProxy()) { |
2711 { StackValueContext context(this); | 2714 { StackValueContext context(this); |
2712 EmitVariableLoad(callee->AsVariableProxy()); | 2715 EmitVariableLoad(callee->AsVariableProxy()); |
2713 PrepareForBailout(callee, NO_REGISTERS); | 2716 PrepareForBailout(callee, NO_REGISTERS); |
2714 } | 2717 } |
2715 // Push undefined as receiver. This is patched in the method prologue if it | 2718 // Push undefined as receiver. This is patched in the method prologue if it |
2716 // is a sloppy mode method. | 2719 // is a sloppy mode method. |
2717 __ push(Immediate(isolate()->factory()->undefined_value())); | 2720 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 2721 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2718 } else { | 2722 } else { |
2719 // Load the function from the receiver. | 2723 // Load the function from the receiver. |
2720 DCHECK(callee->IsProperty()); | 2724 DCHECK(callee->IsProperty()); |
2721 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2725 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2722 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2726 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2723 EmitNamedPropertyLoad(callee->AsProperty()); | 2727 EmitNamedPropertyLoad(callee->AsProperty()); |
2724 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2728 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2725 // Push the target function under the receiver. | 2729 // Push the target function under the receiver. |
2726 __ push(Operand(esp, 0)); | 2730 __ push(Operand(esp, 0)); |
2727 __ mov(Operand(esp, kPointerSize), eax); | 2731 __ mov(Operand(esp, kPointerSize), eax); |
| 2732 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2728 } | 2733 } |
2729 | 2734 |
2730 EmitCall(expr); | 2735 EmitCall(expr, convert_mode); |
2731 } | 2736 } |
2732 | 2737 |
2733 | 2738 |
2734 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2739 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2735 SetExpressionPosition(expr); | 2740 SetExpressionPosition(expr); |
2736 Expression* callee = expr->expression(); | 2741 Expression* callee = expr->expression(); |
2737 DCHECK(callee->IsProperty()); | 2742 DCHECK(callee->IsProperty()); |
2738 Property* prop = callee->AsProperty(); | 2743 Property* prop = callee->AsProperty(); |
2739 DCHECK(prop->IsSuperAccess()); | 2744 DCHECK(prop->IsSuperAccess()); |
2740 | 2745 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2780 DCHECK(callee->IsProperty()); | 2785 DCHECK(callee->IsProperty()); |
2781 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2786 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2782 __ mov(LoadDescriptor::NameRegister(), eax); | 2787 __ mov(LoadDescriptor::NameRegister(), eax); |
2783 EmitKeyedPropertyLoad(callee->AsProperty()); | 2788 EmitKeyedPropertyLoad(callee->AsProperty()); |
2784 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2789 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2785 | 2790 |
2786 // Push the target function under the receiver. | 2791 // Push the target function under the receiver. |
2787 __ push(Operand(esp, 0)); | 2792 __ push(Operand(esp, 0)); |
2788 __ mov(Operand(esp, kPointerSize), eax); | 2793 __ mov(Operand(esp, kPointerSize), eax); |
2789 | 2794 |
2790 EmitCall(expr); | 2795 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2791 } | 2796 } |
2792 | 2797 |
2793 | 2798 |
2794 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2799 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2795 Expression* callee = expr->expression(); | 2800 Expression* callee = expr->expression(); |
2796 DCHECK(callee->IsProperty()); | 2801 DCHECK(callee->IsProperty()); |
2797 Property* prop = callee->AsProperty(); | 2802 Property* prop = callee->AsProperty(); |
2798 DCHECK(prop->IsSuperAccess()); | 2803 DCHECK(prop->IsSuperAccess()); |
2799 | 2804 |
2800 SetExpressionPosition(prop); | 2805 SetExpressionPosition(prop); |
(...skipping 18 matching lines...) Expand all Loading... |
2819 // Replace home_object with target function. | 2824 // Replace home_object with target function. |
2820 __ mov(Operand(esp, kPointerSize), eax); | 2825 __ mov(Operand(esp, kPointerSize), eax); |
2821 | 2826 |
2822 // Stack here: | 2827 // Stack here: |
2823 // - target function | 2828 // - target function |
2824 // - this (receiver) | 2829 // - this (receiver) |
2825 EmitCall(expr); | 2830 EmitCall(expr); |
2826 } | 2831 } |
2827 | 2832 |
2828 | 2833 |
2829 void FullCodeGenerator::EmitCall(Call* expr) { | 2834 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
2830 // Load the arguments. | 2835 // Load the arguments. |
2831 ZoneList<Expression*>* args = expr->arguments(); | 2836 ZoneList<Expression*>* args = expr->arguments(); |
2832 int arg_count = args->length(); | 2837 int arg_count = args->length(); |
2833 for (int i = 0; i < arg_count; i++) { | 2838 for (int i = 0; i < arg_count; i++) { |
2834 VisitForStackValue(args->at(i)); | 2839 VisitForStackValue(args->at(i)); |
2835 } | 2840 } |
2836 | 2841 |
2837 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2842 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2838 SetCallPosition(expr, arg_count); | 2843 SetCallPosition(expr, arg_count); |
2839 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code(); | 2844 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, mode).code(); |
2840 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2845 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2841 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2846 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2842 // Don't assign a type feedback id to the IC, since type feedback is provided | 2847 // Don't assign a type feedback id to the IC, since type feedback is provided |
2843 // by the vector above. | 2848 // by the vector above. |
2844 CallIC(ic); | 2849 CallIC(ic); |
2845 | 2850 |
2846 RecordJSReturnSite(expr); | 2851 RecordJSReturnSite(expr); |
2847 | 2852 |
2848 // Restore context register. | 2853 // Restore context register. |
2849 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2854 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4145 } | 4150 } |
4146 | 4151 |
4147 | 4152 |
4148 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4153 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4149 ZoneList<Expression*>* args = expr->arguments(); | 4154 ZoneList<Expression*>* args = expr->arguments(); |
4150 int arg_count = args->length(); | 4155 int arg_count = args->length(); |
4151 | 4156 |
4152 SetCallPosition(expr, arg_count); | 4157 SetCallPosition(expr, arg_count); |
4153 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 4158 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
4154 __ Set(eax, arg_count); | 4159 __ Set(eax, arg_count); |
4155 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 4160 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 4161 RelocInfo::CODE_TARGET); |
4156 } | 4162 } |
4157 | 4163 |
4158 | 4164 |
4159 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4165 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4160 ZoneList<Expression*>* args = expr->arguments(); | 4166 ZoneList<Expression*>* args = expr->arguments(); |
4161 int arg_count = args->length(); | 4167 int arg_count = args->length(); |
4162 | 4168 |
4163 if (expr->is_jsruntime()) { | 4169 if (expr->is_jsruntime()) { |
4164 Comment cmnt(masm_, "[ CallRuntime"); | 4170 Comment cmnt(masm_, "[ CallRuntime"); |
4165 EmitLoadJSRuntimeFunction(expr); | 4171 EmitLoadJSRuntimeFunction(expr); |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4954 Assembler::target_address_at(call_target_address, | 4960 Assembler::target_address_at(call_target_address, |
4955 unoptimized_code)); | 4961 unoptimized_code)); |
4956 return OSR_AFTER_STACK_CHECK; | 4962 return OSR_AFTER_STACK_CHECK; |
4957 } | 4963 } |
4958 | 4964 |
4959 | 4965 |
4960 } // namespace internal | 4966 } // namespace internal |
4961 } // namespace v8 | 4967 } // namespace v8 |
4962 | 4968 |
4963 #endif // V8_TARGET_ARCH_IA32 | 4969 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |