| 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-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 4696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4707 __ j(not_equal, &new_object); | 4707 __ j(not_equal, &new_object); |
| 4708 | 4708 |
| 4709 // Allocate the JSObject on the heap. | 4709 // Allocate the JSObject on the heap. |
| 4710 Label allocate, done_allocate; | 4710 Label allocate, done_allocate; |
| 4711 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); | 4711 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4712 __ lea(ebx, Operand(ebx, times_pointer_size, 0)); | 4712 __ lea(ebx, Operand(ebx, times_pointer_size, 0)); |
| 4713 __ Allocate(ebx, eax, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4713 __ Allocate(ebx, eax, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 4714 __ bind(&done_allocate); | 4714 __ bind(&done_allocate); |
| 4715 | 4715 |
| 4716 // Initialize the JSObject fields. | 4716 // Initialize the JSObject fields. |
| 4717 __ mov(Operand(eax, JSObject::kMapOffset), ecx); | 4717 __ mov(FieldOperand(eax, JSObject::kMapOffset), ecx); |
| 4718 __ mov(Operand(eax, JSObject::kPropertiesOffset), | 4718 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
| 4719 masm->isolate()->factory()->empty_fixed_array()); | 4719 masm->isolate()->factory()->empty_fixed_array()); |
| 4720 __ mov(Operand(eax, JSObject::kElementsOffset), | 4720 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
| 4721 masm->isolate()->factory()->empty_fixed_array()); | 4721 masm->isolate()->factory()->empty_fixed_array()); |
| 4722 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); | 4722 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 4723 __ lea(ebx, Operand(eax, JSObject::kHeaderSize)); | 4723 __ lea(ebx, FieldOperand(eax, JSObject::kHeaderSize)); |
| 4724 | 4724 |
| 4725 // ----------- S t a t e ------------- | 4725 // ----------- S t a t e ------------- |
| 4726 // -- eax : result (untagged) | 4726 // -- eax : result (tagged) |
| 4727 // -- ebx : result fields (untagged) | 4727 // -- ebx : result fields (untagged) |
| 4728 // -- edi : result end (untagged) | 4728 // -- edi : result end (untagged) |
| 4729 // -- ecx : initial map | 4729 // -- ecx : initial map |
| 4730 // -- esi : context | 4730 // -- esi : context |
| 4731 // -- esp[0] : return address | 4731 // -- esp[0] : return address |
| 4732 // ----------------------------------- | 4732 // ----------------------------------- |
| 4733 | 4733 |
| 4734 // Perform in-object slack tracking if requested. | 4734 // Perform in-object slack tracking if requested. |
| 4735 Label slack_tracking; | 4735 Label slack_tracking; |
| 4736 STATIC_ASSERT(Map::kNoSlackTracking == 0); | 4736 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
| 4737 __ test(FieldOperand(ecx, Map::kBitField3Offset), | 4737 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4738 Immediate(Map::ConstructionCounter::kMask)); | 4738 Immediate(Map::ConstructionCounter::kMask)); |
| 4739 __ j(not_zero, &slack_tracking, Label::kNear); | 4739 __ j(not_zero, &slack_tracking, Label::kNear); |
| 4740 { | 4740 { |
| 4741 // Initialize all in-object fields with undefined. | 4741 // Initialize all in-object fields with undefined. |
| 4742 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); | 4742 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); |
| 4743 __ InitializeFieldsWithFiller(ebx, edi, edx); | 4743 __ InitializeFieldsWithFiller(ebx, edi, edx); |
| 4744 | |
| 4745 // Add the object tag to make the JSObject real. | |
| 4746 STATIC_ASSERT(kHeapObjectTag == 1); | |
| 4747 __ inc(eax); | |
| 4748 __ Ret(); | 4744 __ Ret(); |
| 4749 } | 4745 } |
| 4750 __ bind(&slack_tracking); | 4746 __ bind(&slack_tracking); |
| 4751 { | 4747 { |
| 4752 // Decrease generous allocation count. | 4748 // Decrease generous allocation count. |
| 4753 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | 4749 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
| 4754 __ sub(FieldOperand(ecx, Map::kBitField3Offset), | 4750 __ sub(FieldOperand(ecx, Map::kBitField3Offset), |
| 4755 Immediate(1 << Map::ConstructionCounter::kShift)); | 4751 Immediate(1 << Map::ConstructionCounter::kShift)); |
| 4756 | 4752 |
| 4757 // Initialize the in-object fields with undefined. | 4753 // Initialize the in-object fields with undefined. |
| 4758 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); | 4754 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4759 __ neg(edx); | 4755 __ neg(edx); |
| 4760 __ lea(edx, Operand(edi, edx, times_pointer_size, 0)); | 4756 __ lea(edx, Operand(edi, edx, times_pointer_size, 0)); |
| 4761 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); | 4757 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); |
| 4762 __ InitializeFieldsWithFiller(ebx, edx, edi); | 4758 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4763 | 4759 |
| 4764 // Initialize the remaining (reserved) fields with one pointer filler map. | 4760 // Initialize the remaining (reserved) fields with one pointer filler map. |
| 4765 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); | 4761 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4766 __ lea(edx, Operand(ebx, edx, times_pointer_size, 0)); | 4762 __ lea(edx, Operand(ebx, edx, times_pointer_size, 0)); |
| 4767 __ LoadRoot(edi, Heap::kOnePointerFillerMapRootIndex); | 4763 __ LoadRoot(edi, Heap::kOnePointerFillerMapRootIndex); |
| 4768 __ InitializeFieldsWithFiller(ebx, edx, edi); | 4764 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4769 | 4765 |
| 4770 // Add the object tag to make the JSObject real. | |
| 4771 STATIC_ASSERT(kHeapObjectTag == 1); | |
| 4772 __ inc(eax); | |
| 4773 | |
| 4774 // Check if we can finalize the instance size. | 4766 // Check if we can finalize the instance size. |
| 4775 Label finalize; | 4767 Label finalize; |
| 4776 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); | 4768 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
| 4777 __ test(FieldOperand(ecx, Map::kBitField3Offset), | 4769 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4778 Immediate(Map::ConstructionCounter::kMask)); | 4770 Immediate(Map::ConstructionCounter::kMask)); |
| 4779 __ j(zero, &finalize, Label::kNear); | 4771 __ j(zero, &finalize, Label::kNear); |
| 4780 __ Ret(); | 4772 __ Ret(); |
| 4781 | 4773 |
| 4782 // Finalize the instance size. | 4774 // Finalize the instance size. |
| 4783 __ bind(&finalize); | 4775 __ bind(&finalize); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4794 // Fall back to %AllocateInNewSpace. | 4786 // Fall back to %AllocateInNewSpace. |
| 4795 __ bind(&allocate); | 4787 __ bind(&allocate); |
| 4796 { | 4788 { |
| 4797 FrameScope scope(masm, StackFrame::INTERNAL); | 4789 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4798 __ SmiTag(ebx); | 4790 __ SmiTag(ebx); |
| 4799 __ Push(ecx); | 4791 __ Push(ecx); |
| 4800 __ Push(ebx); | 4792 __ Push(ebx); |
| 4801 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4793 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4802 __ Pop(ecx); | 4794 __ Pop(ecx); |
| 4803 } | 4795 } |
| 4804 STATIC_ASSERT(kHeapObjectTag == 1); | |
| 4805 __ dec(eax); | |
| 4806 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); | 4796 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4807 __ lea(edi, Operand(eax, ebx, times_pointer_size, 0)); | 4797 __ lea(edi, Operand(eax, ebx, times_pointer_size, 0)); |
| 4798 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4799 __ dec(edi); |
| 4808 __ jmp(&done_allocate); | 4800 __ jmp(&done_allocate); |
| 4809 | 4801 |
| 4810 // Fall back to %NewObject. | 4802 // Fall back to %NewObject. |
| 4811 __ bind(&new_object); | 4803 __ bind(&new_object); |
| 4812 __ PopReturnAddressTo(ecx); | 4804 __ PopReturnAddressTo(ecx); |
| 4813 __ Push(edi); | 4805 __ Push(edi); |
| 4814 __ Push(edx); | 4806 __ Push(edx); |
| 4815 __ PushReturnAddressFrom(ecx); | 4807 __ PushReturnAddressFrom(ecx); |
| 4816 __ TailCallRuntime(Runtime::kNewObject); | 4808 __ TailCallRuntime(Runtime::kNewObject); |
| 4817 } | 4809 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4861 // Return an empty rest parameter array. | 4853 // Return an empty rest parameter array. |
| 4862 __ bind(&no_rest_parameters); | 4854 __ bind(&no_rest_parameters); |
| 4863 { | 4855 { |
| 4864 // ----------- S t a t e ------------- | 4856 // ----------- S t a t e ------------- |
| 4865 // -- esi : context | 4857 // -- esi : context |
| 4866 // -- esp[0] : return address | 4858 // -- esp[0] : return address |
| 4867 // ----------------------------------- | 4859 // ----------------------------------- |
| 4868 | 4860 |
| 4869 // Allocate an empty rest parameter array. | 4861 // Allocate an empty rest parameter array. |
| 4870 Label allocate, done_allocate; | 4862 Label allocate, done_allocate; |
| 4871 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, TAG_OBJECT); | 4863 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); |
| 4872 __ bind(&done_allocate); | 4864 __ bind(&done_allocate); |
| 4873 | 4865 |
| 4874 // Setup the rest parameter array in rax. | 4866 // Setup the rest parameter array in rax. |
| 4875 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); | 4867 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
| 4876 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); | 4868 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
| 4877 __ mov(ecx, isolate()->factory()->empty_fixed_array()); | 4869 __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
| 4878 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); | 4870 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
| 4879 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); | 4871 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
| 4880 __ mov(FieldOperand(eax, JSArray::kLengthOffset), | 4872 __ mov(FieldOperand(eax, JSArray::kLengthOffset), |
| 4881 Immediate(Smi::FromInt(0))); | 4873 Immediate(Smi::FromInt(0))); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4903 // -- esi : context | 4895 // -- esi : context |
| 4904 // -- eax : number of rest parameters (tagged) | 4896 // -- eax : number of rest parameters (tagged) |
| 4905 // -- ebx : pointer to first rest parameters | 4897 // -- ebx : pointer to first rest parameters |
| 4906 // -- esp[0] : return address | 4898 // -- esp[0] : return address |
| 4907 // ----------------------------------- | 4899 // ----------------------------------- |
| 4908 | 4900 |
| 4909 // Allocate space for the rest parameter array plus the backing store. | 4901 // Allocate space for the rest parameter array plus the backing store. |
| 4910 Label allocate, done_allocate; | 4902 Label allocate, done_allocate; |
| 4911 __ lea(ecx, Operand(eax, times_half_pointer_size, | 4903 __ lea(ecx, Operand(eax, times_half_pointer_size, |
| 4912 JSArray::kSize + FixedArray::kHeaderSize)); | 4904 JSArray::kSize + FixedArray::kHeaderSize)); |
| 4913 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT); | 4905 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 4914 __ bind(&done_allocate); | 4906 __ bind(&done_allocate); |
| 4915 | 4907 |
| 4916 // Setup the elements array in edx. | 4908 // Setup the elements array in edx. |
| 4917 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 4909 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
| 4918 isolate()->factory()->fixed_array_map()); | 4910 isolate()->factory()->fixed_array_map()); |
| 4919 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 4911 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
| 4920 { | 4912 { |
| 4921 Label loop, done_loop; | 4913 Label loop, done_loop; |
| 4922 __ Move(ecx, Smi::FromInt(0)); | 4914 __ Move(ecx, Smi::FromInt(0)); |
| 4923 __ bind(&loop); | 4915 __ bind(&loop); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5043 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); | 5035 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); |
| 5044 __ bind(&no_parameter_map); | 5036 __ bind(&no_parameter_map); |
| 5045 | 5037 |
| 5046 // 2. Backing store. | 5038 // 2. Backing store. |
| 5047 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); | 5039 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); |
| 5048 | 5040 |
| 5049 // 3. Arguments object. | 5041 // 3. Arguments object. |
| 5050 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize)); | 5042 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize)); |
| 5051 | 5043 |
| 5052 // Do the allocation of all three objects in one go. | 5044 // Do the allocation of all three objects in one go. |
| 5053 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT); | 5045 __ Allocate(ebx, eax, edi, no_reg, &runtime, NO_ALLOCATION_FLAGS); |
| 5054 | 5046 |
| 5055 // eax = address of new object(s) (tagged) | 5047 // eax = address of new object(s) (tagged) |
| 5056 // ecx = argument count (smi-tagged) | 5048 // ecx = argument count (smi-tagged) |
| 5057 // esp[0] = mapped parameter count (tagged) | 5049 // esp[0] = mapped parameter count (tagged) |
| 5058 // esp[4] = function | 5050 // esp[4] = function |
| 5059 // esp[8] = parameter count (tagged) | 5051 // esp[8] = parameter count (tagged) |
| 5060 // Get the arguments map from the current native context into edi. | 5052 // Get the arguments map from the current native context into edi. |
| 5061 Label has_mapped_parameters, instantiate; | 5053 Label has_mapped_parameters, instantiate; |
| 5062 __ mov(edi, NativeContextOperand()); | 5054 __ mov(edi, NativeContextOperand()); |
| 5063 __ mov(ebx, Operand(esp, 0 * kPointerSize)); | 5055 __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5273 // -- ebx : pointer to the first argument | 5265 // -- ebx : pointer to the first argument |
| 5274 // -- esi : context | 5266 // -- esi : context |
| 5275 // -- esp[0] : return address | 5267 // -- esp[0] : return address |
| 5276 // ----------------------------------- | 5268 // ----------------------------------- |
| 5277 | 5269 |
| 5278 // Allocate space for the strict arguments object plus the backing store. | 5270 // Allocate space for the strict arguments object plus the backing store. |
| 5279 Label allocate, done_allocate; | 5271 Label allocate, done_allocate; |
| 5280 __ lea(ecx, | 5272 __ lea(ecx, |
| 5281 Operand(eax, times_half_pointer_size, | 5273 Operand(eax, times_half_pointer_size, |
| 5282 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); | 5274 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); |
| 5283 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT); | 5275 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 5284 __ bind(&done_allocate); | 5276 __ bind(&done_allocate); |
| 5285 | 5277 |
| 5286 // Setup the elements array in edx. | 5278 // Setup the elements array in edx. |
| 5287 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 5279 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
| 5288 isolate()->factory()->fixed_array_map()); | 5280 isolate()->factory()->fixed_array_map()); |
| 5289 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 5281 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
| 5290 { | 5282 { |
| 5291 Label loop, done_loop; | 5283 Label loop, done_loop; |
| 5292 __ Move(ecx, Smi::FromInt(0)); | 5284 __ Move(ecx, Smi::FromInt(0)); |
| 5293 __ bind(&loop); | 5285 __ bind(&loop); |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5861 kStackUnwindSpace, nullptr, return_value_operand, | 5853 kStackUnwindSpace, nullptr, return_value_operand, |
| 5862 NULL); | 5854 NULL); |
| 5863 } | 5855 } |
| 5864 | 5856 |
| 5865 #undef __ | 5857 #undef __ |
| 5866 | 5858 |
| 5867 } // namespace internal | 5859 } // namespace internal |
| 5868 } // namespace v8 | 5860 } // namespace v8 |
| 5869 | 5861 |
| 5870 #endif // V8_TARGET_ARCH_IA32 | 5862 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |