| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 __ jmp(&try_allocate, Label::kNear); | 702 __ jmp(&try_allocate, Label::kNear); |
| 703 | 703 |
| 704 // We have an adaptor frame. Patch the parameters pointer. | 704 // We have an adaptor frame. Patch the parameters pointer. |
| 705 __ bind(&adaptor_frame); | 705 __ bind(&adaptor_frame); |
| 706 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 706 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 707 __ lea(edx, Operand(edx, ecx, times_2, | 707 __ lea(edx, Operand(edx, ecx, times_2, |
| 708 StandardFrameConstants::kCallerSPOffset)); | 708 StandardFrameConstants::kCallerSPOffset)); |
| 709 __ mov(Operand(esp, 2 * kPointerSize), edx); | 709 __ mov(Operand(esp, 2 * kPointerSize), edx); |
| 710 | 710 |
| 711 // ebx = parameter count (tagged) | 711 // ebx = parameter count (tagged) |
| 712 // ecx = argument count (tagged) | 712 // ecx = argument count (smi-tagged) |
| 713 // esp[4] = parameter count (tagged) | 713 // esp[4] = parameter count (tagged) |
| 714 // esp[8] = address of receiver argument | 714 // esp[8] = address of receiver argument |
| 715 // Compute the mapped parameter count = min(ebx, ecx) in ebx. | 715 // Compute the mapped parameter count = min(ebx, ecx) in ebx. |
| 716 __ cmp(ebx, ecx); | 716 __ cmp(ebx, ecx); |
| 717 __ j(less_equal, &try_allocate, Label::kNear); | 717 __ j(less_equal, &try_allocate, Label::kNear); |
| 718 __ mov(ebx, ecx); | 718 __ mov(ebx, ecx); |
| 719 | 719 |
| 720 __ bind(&try_allocate); | 720 __ bind(&try_allocate); |
| 721 | 721 |
| 722 // Save mapped parameter count. | 722 // Save mapped parameter count. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 735 // 2. Backing store. | 735 // 2. Backing store. |
| 736 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); | 736 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); |
| 737 | 737 |
| 738 // 3. Arguments object. | 738 // 3. Arguments object. |
| 739 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); | 739 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); |
| 740 | 740 |
| 741 // Do the allocation of all three objects in one go. | 741 // Do the allocation of all three objects in one go. |
| 742 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); | 742 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); |
| 743 | 743 |
| 744 // eax = address of new object(s) (tagged) | 744 // eax = address of new object(s) (tagged) |
| 745 // ecx = argument count (tagged) | 745 // ecx = argument count (smi-tagged) |
| 746 // esp[0] = mapped parameter count (tagged) | 746 // esp[0] = mapped parameter count (tagged) |
| 747 // esp[8] = parameter count (tagged) | 747 // esp[8] = parameter count (tagged) |
| 748 // esp[12] = address of receiver argument | 748 // esp[12] = address of receiver argument |
| 749 // Get the arguments boilerplate from the current native context into edi. | 749 // Get the arguments map from the current native context into edi. |
| 750 Label has_mapped_parameters, copy; | 750 Label has_mapped_parameters, instantiate; |
| 751 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 751 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 752 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); | 752 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
| 753 __ mov(ebx, Operand(esp, 0 * kPointerSize)); | 753 __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
| 754 __ test(ebx, ebx); | 754 __ test(ebx, ebx); |
| 755 __ j(not_zero, &has_mapped_parameters, Label::kNear); | 755 __ j(not_zero, &has_mapped_parameters, Label::kNear); |
| 756 __ mov(edi, Operand(edi, | 756 __ mov( |
| 757 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX))); | 757 edi, |
| 758 __ jmp(©, Label::kNear); | 758 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); |
| 759 __ jmp(&instantiate, Label::kNear); |
| 759 | 760 |
| 760 __ bind(&has_mapped_parameters); | 761 __ bind(&has_mapped_parameters); |
| 761 __ mov(edi, Operand(edi, | 762 __ mov( |
| 762 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); | 763 edi, |
| 763 __ bind(©); | 764 Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX))); |
| 765 __ bind(&instantiate); |
| 764 | 766 |
| 765 // eax = address of new object (tagged) | 767 // eax = address of new object (tagged) |
| 766 // ebx = mapped parameter count (tagged) | 768 // ebx = mapped parameter count (tagged) |
| 767 // ecx = argument count (tagged) | 769 // ecx = argument count (smi-tagged) |
| 768 // edi = address of boilerplate object (tagged) | 770 // edi = address of arguments map (tagged) |
| 769 // esp[0] = mapped parameter count (tagged) | 771 // esp[0] = mapped parameter count (tagged) |
| 770 // esp[8] = parameter count (tagged) | 772 // esp[8] = parameter count (tagged) |
| 771 // esp[12] = address of receiver argument | 773 // esp[12] = address of receiver argument |
| 772 // Copy the JS object part. | 774 // Copy the JS object part. |
| 773 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 775 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); |
| 774 __ mov(edx, FieldOperand(edi, i)); | 776 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
| 775 __ mov(FieldOperand(eax, i), edx); | 777 masm->isolate()->factory()->empty_fixed_array()); |
| 776 } | 778 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
| 779 masm->isolate()->factory()->empty_fixed_array()); |
| 777 | 780 |
| 778 // Set up the callee in-object property. | 781 // Set up the callee in-object property. |
| 779 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 782 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
| 780 __ mov(edx, Operand(esp, 4 * kPointerSize)); | 783 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
| 784 __ AssertNotSmi(edx); |
| 781 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 785 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 782 Heap::kArgumentsCalleeIndex * kPointerSize), | 786 Heap::kArgumentsCalleeIndex * kPointerSize), |
| 783 edx); | 787 edx); |
| 784 | 788 |
| 785 // Use the length (smi tagged) and set that as an in-object property too. | 789 // Use the length (smi tagged) and set that as an in-object property too. |
| 790 __ AssertSmi(ecx); |
| 786 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 791 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
| 787 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 792 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 788 Heap::kArgumentsLengthIndex * kPointerSize), | 793 Heap::kArgumentsLengthIndex * kPointerSize), |
| 789 ecx); | 794 ecx); |
| 790 | 795 |
| 791 // Set up the elements pointer in the allocated arguments object. | 796 // Set up the elements pointer in the allocated arguments object. |
| 792 // If we allocated a parameter map, edi will point there, otherwise to the | 797 // If we allocated a parameter map, edi will point there, otherwise to the |
| 793 // backing store. | 798 // backing store. |
| 794 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); | 799 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); |
| 795 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | 800 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 __ bind(&try_allocate); | 937 __ bind(&try_allocate); |
| 933 __ test(ecx, ecx); | 938 __ test(ecx, ecx); |
| 934 __ j(zero, &add_arguments_object, Label::kNear); | 939 __ j(zero, &add_arguments_object, Label::kNear); |
| 935 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 940 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
| 936 __ bind(&add_arguments_object); | 941 __ bind(&add_arguments_object); |
| 937 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); | 942 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); |
| 938 | 943 |
| 939 // Do the allocation of both objects in one go. | 944 // Do the allocation of both objects in one go. |
| 940 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 945 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
| 941 | 946 |
| 942 // Get the arguments boilerplate from the current native context. | 947 // Get the arguments map from the current native context. |
| 943 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 948 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 944 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); | 949 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
| 945 const int offset = | 950 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); |
| 946 Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX); | |
| 947 __ mov(edi, Operand(edi, offset)); | 951 __ mov(edi, Operand(edi, offset)); |
| 948 | 952 |
| 949 // Copy the JS object part. | 953 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); |
| 950 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 954 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
| 951 __ mov(ebx, FieldOperand(edi, i)); | 955 masm->isolate()->factory()->empty_fixed_array()); |
| 952 __ mov(FieldOperand(eax, i), ebx); | 956 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
| 953 } | 957 masm->isolate()->factory()->empty_fixed_array()); |
| 954 | 958 |
| 955 // Get the length (smi tagged) and set that as an in-object property too. | 959 // Get the length (smi tagged) and set that as an in-object property too. |
| 956 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 960 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
| 957 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 961 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
| 962 __ AssertSmi(ecx); |
| 958 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 963 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 959 Heap::kArgumentsLengthIndex * kPointerSize), | 964 Heap::kArgumentsLengthIndex * kPointerSize), |
| 960 ecx); | 965 ecx); |
| 961 | 966 |
| 962 // If there are no actual arguments, we're done. | 967 // If there are no actual arguments, we're done. |
| 963 Label done; | 968 Label done; |
| 964 __ test(ecx, ecx); | 969 __ test(ecx, ecx); |
| 965 __ j(zero, &done, Label::kNear); | 970 __ j(zero, &done, Label::kNear); |
| 966 | 971 |
| 967 // Get the parameters pointer from the stack. | 972 // Get the parameters pointer from the stack. |
| (...skipping 3660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4628 Operand(ebp, 7 * kPointerSize), | 4633 Operand(ebp, 7 * kPointerSize), |
| 4629 NULL); | 4634 NULL); |
| 4630 } | 4635 } |
| 4631 | 4636 |
| 4632 | 4637 |
| 4633 #undef __ | 4638 #undef __ |
| 4634 | 4639 |
| 4635 } } // namespace v8::internal | 4640 } } // namespace v8::internal |
| 4636 | 4641 |
| 4637 #endif // V8_TARGET_ARCH_X87 | 4642 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |