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 |