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/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 4712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4723 Label fast_elements_case; | 4723 Label fast_elements_case; |
4724 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 4724 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
4725 __ j(equal, &fast_elements_case); | 4725 __ j(equal, &fast_elements_case); |
4726 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4726 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4727 | 4727 |
4728 __ bind(&fast_elements_case); | 4728 __ bind(&fast_elements_case); |
4729 GenerateCase(masm, FAST_ELEMENTS); | 4729 GenerateCase(masm, FAST_ELEMENTS); |
4730 } | 4730 } |
4731 | 4731 |
4732 | 4732 |
| 4733 void FastNewObjectStub::Generate(MacroAssembler* masm) { |
| 4734 // ----------- S t a t e ------------- |
| 4735 // -- edi : target |
| 4736 // -- edx : new target |
| 4737 // -- esi : context |
| 4738 // -- esp[0] : return address |
| 4739 // ----------------------------------- |
| 4740 __ AssertFunction(edi); |
| 4741 __ AssertReceiver(edx); |
| 4742 |
| 4743 // Verify that the new target is a JSFunction. |
| 4744 Label new_object; |
| 4745 __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx); |
| 4746 __ j(not_equal, &new_object); |
| 4747 |
| 4748 // Load the initial map and verify that it's in fact a map. |
| 4749 __ mov(ecx, FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4750 __ JumpIfSmi(ecx, &new_object); |
| 4751 __ CmpObjectType(ecx, MAP_TYPE, ebx); |
| 4752 __ j(not_equal, &new_object); |
| 4753 |
| 4754 // Fall back to runtime if the target differs from the new target's |
| 4755 // initial map constructor. |
| 4756 __ cmp(edi, FieldOperand(ecx, Map::kConstructorOrBackPointerOffset)); |
| 4757 __ j(not_equal, &new_object); |
| 4758 |
| 4759 // Allocate the JSObject on the heap. |
| 4760 Label allocate, done_allocate; |
| 4761 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4762 __ lea(ebx, Operand(ebx, times_pointer_size, 0)); |
| 4763 __ Allocate(ebx, eax, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 4764 __ bind(&done_allocate); |
| 4765 |
| 4766 // Initialize the JSObject fields. |
| 4767 __ mov(Operand(eax, JSObject::kMapOffset), ecx); |
| 4768 __ mov(Operand(eax, JSObject::kPropertiesOffset), |
| 4769 masm->isolate()->factory()->empty_fixed_array()); |
| 4770 __ mov(Operand(eax, JSObject::kElementsOffset), |
| 4771 masm->isolate()->factory()->empty_fixed_array()); |
| 4772 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 4773 __ lea(ebx, Operand(eax, JSObject::kHeaderSize)); |
| 4774 |
| 4775 // ----------- S t a t e ------------- |
| 4776 // -- eax : result (untagged) |
| 4777 // -- ebx : result fields (untagged) |
| 4778 // -- edi : result end (untagged) |
| 4779 // -- ecx : initial map |
| 4780 // -- esi : context |
| 4781 // -- esp[0] : return address |
| 4782 // ----------------------------------- |
| 4783 |
| 4784 // Perform in-object slack tracking if requested. |
| 4785 Label slack_tracking; |
| 4786 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
| 4787 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4788 Immediate(Map::ConstructionCounter::kMask)); |
| 4789 __ j(not_zero, &slack_tracking, Label::kNear); |
| 4790 { |
| 4791 // Initialize all in-object fields with undefined. |
| 4792 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); |
| 4793 __ InitializeFieldsWithFiller(ebx, edi, edx); |
| 4794 |
| 4795 // Add the object tag to make the JSObject real. |
| 4796 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4797 __ inc(eax); |
| 4798 __ Ret(); |
| 4799 } |
| 4800 __ bind(&slack_tracking); |
| 4801 { |
| 4802 // Decrease generous allocation count. |
| 4803 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
| 4804 __ sub(FieldOperand(ecx, Map::kBitField3Offset), |
| 4805 Immediate(1 << Map::ConstructionCounter::kShift)); |
| 4806 |
| 4807 // Initialize the in-object fields with undefined. |
| 4808 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4809 __ neg(edx); |
| 4810 __ lea(edx, Operand(edi, edx, times_pointer_size, 0)); |
| 4811 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); |
| 4812 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4813 |
| 4814 // Initialize the remaining (reserved) fields with one pointer filler map. |
| 4815 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4816 __ lea(edx, Operand(ebx, edx, times_pointer_size, 0)); |
| 4817 __ LoadRoot(edi, Heap::kOnePointerFillerMapRootIndex); |
| 4818 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4819 |
| 4820 // Add the object tag to make the JSObject real. |
| 4821 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4822 __ inc(eax); |
| 4823 |
| 4824 // Check if we can finalize the instance size. |
| 4825 Label finalize; |
| 4826 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
| 4827 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4828 Immediate(Map::ConstructionCounter::kMask)); |
| 4829 __ j(zero, &finalize, Label::kNear); |
| 4830 __ Ret(); |
| 4831 |
| 4832 // Finalize the instance size. |
| 4833 __ bind(&finalize); |
| 4834 { |
| 4835 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4836 __ Push(eax); |
| 4837 __ Push(ecx); |
| 4838 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
| 4839 __ Pop(eax); |
| 4840 } |
| 4841 __ Ret(); |
| 4842 } |
| 4843 |
| 4844 // Fall back to %AllocateInNewSpace. |
| 4845 __ bind(&allocate); |
| 4846 { |
| 4847 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4848 __ SmiTag(ebx); |
| 4849 __ Push(ecx); |
| 4850 __ Push(ebx); |
| 4851 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4852 __ Pop(ecx); |
| 4853 } |
| 4854 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4855 __ dec(eax); |
| 4856 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4857 __ lea(edi, Operand(eax, ebx, times_pointer_size, 0)); |
| 4858 __ jmp(&done_allocate); |
| 4859 |
| 4860 // Fall back to %NewObject. |
| 4861 __ bind(&new_object); |
| 4862 __ PopReturnAddressTo(ecx); |
| 4863 __ Push(edi); |
| 4864 __ Push(edx); |
| 4865 __ PushReturnAddressFrom(ecx); |
| 4866 __ TailCallRuntime(Runtime::kNewObject); |
| 4867 } |
| 4868 |
| 4869 |
4733 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 4870 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
4734 // ----------- S t a t e ------------- | 4871 // ----------- S t a t e ------------- |
4735 // -- edi : function | 4872 // -- edi : function |
4736 // -- esi : context | 4873 // -- esi : context |
4737 // -- ebp : frame pointer | 4874 // -- ebp : frame pointer |
4738 // -- esp[0] : return address | 4875 // -- esp[0] : return address |
4739 // ----------------------------------- | 4876 // ----------------------------------- |
4740 __ AssertFunction(edi); | 4877 __ AssertFunction(edi); |
4741 | 4878 |
4742 // For Ignition we need to skip all possible handler/stub frames until | 4879 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5782 return_value_operand, NULL); | 5919 return_value_operand, NULL); |
5783 } | 5920 } |
5784 | 5921 |
5785 | 5922 |
5786 #undef __ | 5923 #undef __ |
5787 | 5924 |
5788 } // namespace internal | 5925 } // namespace internal |
5789 } // namespace v8 | 5926 } // namespace v8 |
5790 | 5927 |
5791 #endif // V8_TARGET_ARCH_IA32 | 5928 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |