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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2022 __ bind(&l_call); | 2022 __ bind(&l_call); |
2023 __ mov(load_receiver, Operand(esp, kPointerSize)); | 2023 __ mov(load_receiver, Operand(esp, kPointerSize)); |
2024 __ mov(LoadDescriptor::SlotRegister(), | 2024 __ mov(LoadDescriptor::SlotRegister(), |
2025 Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot()))); | 2025 Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot()))); |
2026 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 2026 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
2027 CallIC(ic, TypeFeedbackId::None()); | 2027 CallIC(ic, TypeFeedbackId::None()); |
2028 __ mov(edi, eax); | 2028 __ mov(edi, eax); |
2029 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2029 __ mov(Operand(esp, 2 * kPointerSize), edi); |
2030 SetCallPosition(expr, 1); | 2030 SetCallPosition(expr, 1); |
2031 __ Set(eax, 1); | 2031 __ Set(eax, 1); |
2032 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2032 __ Call( |
| 2033 isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), |
| 2034 RelocInfo::CODE_TARGET); |
2033 | 2035 |
2034 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2036 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2035 __ Drop(1); // The function is still on the stack; drop it. | 2037 __ Drop(1); // The function is still on the stack; drop it. |
2036 | 2038 |
2037 // if (!result.done) goto l_try; | 2039 // if (!result.done) goto l_try; |
2038 __ bind(&l_loop); | 2040 __ bind(&l_loop); |
2039 __ push(eax); // save result | 2041 __ push(eax); // save result |
2040 __ Move(load_receiver, eax); // result | 2042 __ Move(load_receiver, eax); // result |
2041 __ mov(load_name, | 2043 __ mov(load_name, |
2042 isolate()->factory()->done_string()); // "done" | 2044 isolate()->factory()->done_string()); // "done" |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2692 ic_total_count_++; | 2694 ic_total_count_++; |
2693 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2695 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2694 } | 2696 } |
2695 | 2697 |
2696 | 2698 |
2697 // Code common for calls using the IC. | 2699 // Code common for calls using the IC. |
2698 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2700 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2699 Expression* callee = expr->expression(); | 2701 Expression* callee = expr->expression(); |
2700 | 2702 |
2701 // Get the target function. | 2703 // Get the target function. |
| 2704 ConvertReceiverMode convert_mode; |
2702 if (callee->IsVariableProxy()) { | 2705 if (callee->IsVariableProxy()) { |
2703 { StackValueContext context(this); | 2706 { StackValueContext context(this); |
2704 EmitVariableLoad(callee->AsVariableProxy()); | 2707 EmitVariableLoad(callee->AsVariableProxy()); |
2705 PrepareForBailout(callee, NO_REGISTERS); | 2708 PrepareForBailout(callee, NO_REGISTERS); |
2706 } | 2709 } |
2707 // Push undefined as receiver. This is patched in the method prologue if it | 2710 // Push undefined as receiver. This is patched in the method prologue if it |
2708 // is a sloppy mode method. | 2711 // is a sloppy mode method. |
2709 __ push(Immediate(isolate()->factory()->undefined_value())); | 2712 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 2713 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2710 } else { | 2714 } else { |
2711 // Load the function from the receiver. | 2715 // Load the function from the receiver. |
2712 DCHECK(callee->IsProperty()); | 2716 DCHECK(callee->IsProperty()); |
2713 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2717 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2714 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2718 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2715 EmitNamedPropertyLoad(callee->AsProperty()); | 2719 EmitNamedPropertyLoad(callee->AsProperty()); |
2716 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2720 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2717 // Push the target function under the receiver. | 2721 // Push the target function under the receiver. |
2718 __ push(Operand(esp, 0)); | 2722 __ push(Operand(esp, 0)); |
2719 __ mov(Operand(esp, kPointerSize), eax); | 2723 __ mov(Operand(esp, kPointerSize), eax); |
| 2724 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2720 } | 2725 } |
2721 | 2726 |
2722 EmitCall(expr); | 2727 EmitCall(expr, convert_mode); |
2723 } | 2728 } |
2724 | 2729 |
2725 | 2730 |
2726 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2731 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2727 SetExpressionPosition(expr); | 2732 SetExpressionPosition(expr); |
2728 Expression* callee = expr->expression(); | 2733 Expression* callee = expr->expression(); |
2729 DCHECK(callee->IsProperty()); | 2734 DCHECK(callee->IsProperty()); |
2730 Property* prop = callee->AsProperty(); | 2735 Property* prop = callee->AsProperty(); |
2731 DCHECK(prop->IsSuperAccess()); | 2736 DCHECK(prop->IsSuperAccess()); |
2732 | 2737 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2772 DCHECK(callee->IsProperty()); | 2777 DCHECK(callee->IsProperty()); |
2773 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2778 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2774 __ mov(LoadDescriptor::NameRegister(), eax); | 2779 __ mov(LoadDescriptor::NameRegister(), eax); |
2775 EmitKeyedPropertyLoad(callee->AsProperty()); | 2780 EmitKeyedPropertyLoad(callee->AsProperty()); |
2776 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2781 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2777 | 2782 |
2778 // Push the target function under the receiver. | 2783 // Push the target function under the receiver. |
2779 __ push(Operand(esp, 0)); | 2784 __ push(Operand(esp, 0)); |
2780 __ mov(Operand(esp, kPointerSize), eax); | 2785 __ mov(Operand(esp, kPointerSize), eax); |
2781 | 2786 |
2782 EmitCall(expr); | 2787 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2783 } | 2788 } |
2784 | 2789 |
2785 | 2790 |
2786 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2791 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2787 Expression* callee = expr->expression(); | 2792 Expression* callee = expr->expression(); |
2788 DCHECK(callee->IsProperty()); | 2793 DCHECK(callee->IsProperty()); |
2789 Property* prop = callee->AsProperty(); | 2794 Property* prop = callee->AsProperty(); |
2790 DCHECK(prop->IsSuperAccess()); | 2795 DCHECK(prop->IsSuperAccess()); |
2791 | 2796 |
2792 SetExpressionPosition(prop); | 2797 SetExpressionPosition(prop); |
(...skipping 18 matching lines...) Expand all Loading... |
2811 // Replace home_object with target function. | 2816 // Replace home_object with target function. |
2812 __ mov(Operand(esp, kPointerSize), eax); | 2817 __ mov(Operand(esp, kPointerSize), eax); |
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(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2837 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2833 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2838 __ mov(edi, Operand(esp, (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 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2846 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4137 } | 4142 } |
4138 | 4143 |
4139 | 4144 |
4140 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4145 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4141 ZoneList<Expression*>* args = expr->arguments(); | 4146 ZoneList<Expression*>* args = expr->arguments(); |
4142 int arg_count = args->length(); | 4147 int arg_count = args->length(); |
4143 | 4148 |
4144 SetCallPosition(expr, arg_count); | 4149 SetCallPosition(expr, arg_count); |
4145 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 4150 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
4146 __ Set(eax, arg_count); | 4151 __ Set(eax, arg_count); |
4147 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 4152 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 4153 RelocInfo::CODE_TARGET); |
4148 } | 4154 } |
4149 | 4155 |
4150 | 4156 |
4151 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4157 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4152 ZoneList<Expression*>* args = expr->arguments(); | 4158 ZoneList<Expression*>* args = expr->arguments(); |
4153 int arg_count = args->length(); | 4159 int arg_count = args->length(); |
4154 | 4160 |
4155 if (expr->is_jsruntime()) { | 4161 if (expr->is_jsruntime()) { |
4156 Comment cmnt(masm_, "[ CallRuntime"); | 4162 Comment cmnt(masm_, "[ CallRuntime"); |
4157 EmitLoadJSRuntimeFunction(expr); | 4163 EmitLoadJSRuntimeFunction(expr); |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4946 Assembler::target_address_at(call_target_address, | 4952 Assembler::target_address_at(call_target_address, |
4947 unoptimized_code)); | 4953 unoptimized_code)); |
4948 return OSR_AFTER_STACK_CHECK; | 4954 return OSR_AFTER_STACK_CHECK; |
4949 } | 4955 } |
4950 | 4956 |
4951 | 4957 |
4952 } // namespace internal | 4958 } // namespace internal |
4953 } // namespace v8 | 4959 } // namespace v8 |
4954 | 4960 |
4955 #endif // V8_TARGET_ARCH_X87 | 4961 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |