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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 __ bind(&runtime); | 783 __ bind(&runtime); |
784 __ pop(eax); // Pop return address. | 784 __ pop(eax); // Pop return address. |
785 __ push(edi); // Push function. | 785 __ push(edi); // Push function. |
786 __ push(edx); // Push parameters pointer. | 786 __ push(edx); // Push parameters pointer. |
787 __ push(ecx); // Push parameter count. | 787 __ push(ecx); // Push parameter count. |
788 __ push(eax); // Push return address. | 788 __ push(eax); // Push return address. |
789 __ TailCallRuntime(Runtime::kNewStrictArguments); | 789 __ TailCallRuntime(Runtime::kNewStrictArguments); |
790 } | 790 } |
791 | 791 |
792 | 792 |
793 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { | |
794 // ecx : number of parameters (tagged) | |
795 // edx : parameters pointer | |
796 // ebx : rest parameter index (tagged) | |
797 // esp[0] : return address | |
798 | |
799 // Check if the calling frame is an arguments adaptor frame. | |
800 Label runtime; | |
801 __ mov(edi, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | |
802 __ mov(eax, Operand(edi, StandardFrameConstants::kContextOffset)); | |
803 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
804 __ j(not_equal, &runtime); | |
805 | |
806 // Patch the arguments.length and the parameters pointer. | |
807 __ mov(ecx, Operand(edi, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
808 __ lea(edx, | |
809 Operand(edi, ecx, times_2, StandardFrameConstants::kCallerSPOffset)); | |
810 | |
811 __ bind(&runtime); | |
812 __ pop(eax); // Save return address. | |
813 __ push(ecx); // Push number of parameters. | |
814 __ push(edx); // Push parameters pointer. | |
815 __ push(ebx); // Push rest parameter index. | |
816 __ push(eax); // Push return address. | |
817 __ TailCallRuntime(Runtime::kNewRestParam); | |
818 } | |
819 | |
820 | |
821 void RegExpExecStub::Generate(MacroAssembler* masm) { | 793 void RegExpExecStub::Generate(MacroAssembler* masm) { |
822 // Just jump directly to runtime if native RegExp is not selected at compile | 794 // Just jump directly to runtime if native RegExp is not selected at compile |
823 // time or if regexp entry in generated code is turned off runtime switch or | 795 // time or if regexp entry in generated code is turned off runtime switch or |
824 // at compilation. | 796 // at compilation. |
825 #ifdef V8_INTERPRETED_REGEXP | 797 #ifdef V8_INTERPRETED_REGEXP |
826 __ TailCallRuntime(Runtime::kRegExpExec); | 798 __ TailCallRuntime(Runtime::kRegExpExec); |
827 #else // V8_INTERPRETED_REGEXP | 799 #else // V8_INTERPRETED_REGEXP |
828 | 800 |
829 // Stack frame on entry. | 801 // Stack frame on entry. |
830 // esp[0]: return address | 802 // esp[0]: return address |
(...skipping 3979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4810 | 4782 |
4811 Label fast_elements_case; | 4783 Label fast_elements_case; |
4812 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 4784 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
4813 __ j(equal, &fast_elements_case); | 4785 __ j(equal, &fast_elements_case); |
4814 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4786 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4815 | 4787 |
4816 __ bind(&fast_elements_case); | 4788 __ bind(&fast_elements_case); |
4817 GenerateCase(masm, FAST_ELEMENTS); | 4789 GenerateCase(masm, FAST_ELEMENTS); |
4818 } | 4790 } |
4819 | 4791 |
| 4792 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 4793 // ----------- S t a t e ------------- |
| 4794 // -- edi : function |
| 4795 // -- esi : context |
| 4796 // -- ebp : frame pointer |
| 4797 // -- esp[0] : return address |
| 4798 // ----------------------------------- |
| 4799 __ AssertFunction(edi); |
| 4800 |
| 4801 // For Ignition we need to skip all possible handler/stub frames until |
| 4802 // we reach the JavaScript frame for the function (similar to what the |
| 4803 // runtime fallback implementation does). So make edx point to that |
| 4804 // JavaScript frame. |
| 4805 { |
| 4806 Label loop, loop_entry; |
| 4807 __ mov(edx, ebp); |
| 4808 __ jmp(&loop_entry, Label::kNear); |
| 4809 __ bind(&loop); |
| 4810 __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
| 4811 __ bind(&loop_entry); |
| 4812 __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset)); |
| 4813 __ j(not_equal, &loop); |
| 4814 } |
| 4815 |
| 4816 // Check if we have rest parameters (only possible if we have an |
| 4817 // arguments adaptor frame below the function frame). |
| 4818 Label no_rest_parameters; |
| 4819 __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
| 4820 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), |
| 4821 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 4822 __ j(not_equal, &no_rest_parameters, Label::kNear); |
| 4823 |
| 4824 // Check if the arguments adaptor frame contains more arguments than |
| 4825 // specified by the function's internal formal parameter count. |
| 4826 Label rest_parameters; |
| 4827 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 4828 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4829 __ sub(eax, |
| 4830 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 4831 __ j(greater, &rest_parameters); |
| 4832 |
| 4833 // Return an empty rest parameter array. |
| 4834 __ bind(&no_rest_parameters); |
| 4835 { |
| 4836 // ----------- S t a t e ------------- |
| 4837 // -- esi : context |
| 4838 // -- esp[0] : return address |
| 4839 // ----------------------------------- |
| 4840 |
| 4841 // Allocate an empty rest parameter array. |
| 4842 Label allocate, done_allocate; |
| 4843 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, TAG_OBJECT); |
| 4844 __ bind(&done_allocate); |
| 4845 |
| 4846 // Setup the rest parameter array in rax. |
| 4847 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
| 4848 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
| 4849 __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
| 4850 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
| 4851 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
| 4852 __ mov(FieldOperand(eax, JSArray::kLengthOffset), |
| 4853 Immediate(Smi::FromInt(0))); |
| 4854 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 4855 __ Ret(); |
| 4856 |
| 4857 // Fall back to %AllocateInNewSpace. |
| 4858 __ bind(&allocate); |
| 4859 { |
| 4860 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4861 __ Push(Smi::FromInt(JSArray::kSize)); |
| 4862 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4863 } |
| 4864 __ jmp(&done_allocate); |
| 4865 } |
| 4866 |
| 4867 __ bind(&rest_parameters); |
| 4868 { |
| 4869 // Compute the pointer to the first rest parameter (skippping the receiver). |
| 4870 __ lea(ebx, |
| 4871 Operand(ebx, eax, times_half_pointer_size, |
| 4872 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
| 4873 |
| 4874 // ----------- S t a t e ------------- |
| 4875 // -- esi : context |
| 4876 // -- eax : number of rest parameters (tagged) |
| 4877 // -- ebx : pointer to first rest parameters |
| 4878 // -- esp[0] : return address |
| 4879 // ----------------------------------- |
| 4880 |
| 4881 // Allocate space for the rest parameter array plus the backing store. |
| 4882 Label allocate, done_allocate; |
| 4883 __ lea(ecx, Operand(eax, times_half_pointer_size, |
| 4884 JSArray::kSize + FixedArray::kHeaderSize)); |
| 4885 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT); |
| 4886 __ bind(&done_allocate); |
| 4887 |
| 4888 // Setup the elements array in edx. |
| 4889 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
| 4890 isolate()->factory()->fixed_array_map()); |
| 4891 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
| 4892 { |
| 4893 Label loop, done_loop; |
| 4894 __ Move(ecx, Smi::FromInt(0)); |
| 4895 __ bind(&loop); |
| 4896 __ cmp(ecx, eax); |
| 4897 __ j(equal, &done_loop, Label::kNear); |
| 4898 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
| 4899 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
| 4900 FixedArray::kHeaderSize), |
| 4901 edi); |
| 4902 __ sub(ebx, Immediate(1 * kPointerSize)); |
| 4903 __ add(ecx, Immediate(Smi::FromInt(1))); |
| 4904 __ jmp(&loop); |
| 4905 __ bind(&done_loop); |
| 4906 } |
| 4907 |
| 4908 // Setup the rest parameter array in edi. |
| 4909 __ lea(edi, |
| 4910 Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize)); |
| 4911 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
| 4912 __ mov(FieldOperand(edi, JSArray::kMapOffset), ecx); |
| 4913 __ mov(FieldOperand(edi, JSArray::kPropertiesOffset), |
| 4914 isolate()->factory()->empty_fixed_array()); |
| 4915 __ mov(FieldOperand(edi, JSArray::kElementsOffset), edx); |
| 4916 __ mov(FieldOperand(edi, JSArray::kLengthOffset), eax); |
| 4917 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 4918 __ mov(eax, edi); |
| 4919 __ Ret(); |
| 4920 |
| 4921 // Fall back to %AllocateInNewSpace. |
| 4922 __ bind(&allocate); |
| 4923 { |
| 4924 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4925 __ SmiTag(ecx); |
| 4926 __ Push(eax); |
| 4927 __ Push(ebx); |
| 4928 __ Push(ecx); |
| 4929 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4930 __ mov(edx, eax); |
| 4931 __ Pop(ebx); |
| 4932 __ Pop(eax); |
| 4933 } |
| 4934 __ jmp(&done_allocate); |
| 4935 } |
| 4936 } |
4820 | 4937 |
4821 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 4938 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
4822 Register context_reg = esi; | 4939 Register context_reg = esi; |
4823 Register slot_reg = ebx; | 4940 Register slot_reg = ebx; |
4824 Register result_reg = eax; | 4941 Register result_reg = eax; |
4825 Label slow_case; | 4942 Label slow_case; |
4826 | 4943 |
4827 // Go up context chain to the script context. | 4944 // Go up context chain to the script context. |
4828 for (int i = 0; i < depth(); ++i) { | 4945 for (int i = 0; i < depth(); ++i) { |
4829 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 4946 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5369 return_value_operand, NULL); | 5486 return_value_operand, NULL); |
5370 } | 5487 } |
5371 | 5488 |
5372 | 5489 |
5373 #undef __ | 5490 #undef __ |
5374 | 5491 |
5375 } // namespace internal | 5492 } // namespace internal |
5376 } // namespace v8 | 5493 } // namespace v8 |
5377 | 5494 |
5378 #endif // V8_TARGET_ARCH_X87 | 5495 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |