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/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4792 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4792 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4793 | 4793 |
4794 __ bind(&fast_elements_case); | 4794 __ bind(&fast_elements_case); |
4795 GenerateCase(masm, FAST_ELEMENTS); | 4795 GenerateCase(masm, FAST_ELEMENTS); |
4796 } | 4796 } |
4797 | 4797 |
4798 | 4798 |
4799 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 4799 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
4800 Register context_reg = esi; | 4800 Register context_reg = esi; |
4801 Register slot_reg = ebx; | 4801 Register slot_reg = ebx; |
4802 Register name_reg = ecx; | |
4803 Register result_reg = eax; | 4802 Register result_reg = eax; |
4804 Label slow_case; | 4803 Label slow_case; |
4805 | 4804 |
4806 // Go up context chain to the script context. | 4805 // Go up context chain to the script context. |
4807 for (int i = 0; i < depth(); ++i) { | 4806 for (int i = 0; i < depth(); ++i) { |
4808 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 4807 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
4809 context_reg = result_reg; | 4808 context_reg = result_reg; |
4810 } | 4809 } |
4811 | 4810 |
4812 // Load the PropertyCell value at the specified slot. | 4811 // Load the PropertyCell value at the specified slot. |
4813 __ mov(result_reg, ContextOperand(context_reg, slot_reg)); | 4812 __ mov(result_reg, ContextOperand(context_reg, slot_reg)); |
4814 __ mov(result_reg, FieldOperand(result_reg, PropertyCell::kValueOffset)); | 4813 __ mov(result_reg, FieldOperand(result_reg, PropertyCell::kValueOffset)); |
4815 | 4814 |
4816 // Check that value is not the_hole. | 4815 // Check that value is not the_hole. |
4817 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); | 4816 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); |
4818 __ j(equal, &slow_case, Label::kNear); | 4817 __ j(equal, &slow_case, Label::kNear); |
4819 __ Ret(); | 4818 __ Ret(); |
4820 | 4819 |
4821 // Fallback to the runtime. | 4820 // Fallback to the runtime. |
4822 __ bind(&slow_case); | 4821 __ bind(&slow_case); |
4823 __ SmiTag(slot_reg); | 4822 __ SmiTag(slot_reg); |
4824 __ Pop(result_reg); // Pop return address. | 4823 __ Pop(result_reg); // Pop return address. |
4825 __ Push(slot_reg); | 4824 __ Push(slot_reg); |
4826 __ Push(name_reg); | |
4827 __ Push(result_reg); // Push return address. | 4825 __ Push(result_reg); // Push return address. |
4828 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 2, 1); | 4826 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1, 1); |
4829 } | 4827 } |
4830 | 4828 |
4831 | 4829 |
4832 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { | 4830 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { |
4833 Register context_reg = esi; | 4831 Register context_reg = esi; |
4834 Register slot_reg = ebx; | 4832 Register slot_reg = ebx; |
4835 Register name_reg = ecx; | |
4836 Register value_reg = eax; | 4833 Register value_reg = eax; |
4837 Register cell_reg = edi; | 4834 Register cell_reg = edi; |
4838 Register cell_details_reg = edx; | 4835 Register cell_details_reg = edx; |
| 4836 Register cell_value_reg = ecx; |
4839 Label fast_heapobject_case, fast_smi_case, slow_case; | 4837 Label fast_heapobject_case, fast_smi_case, slow_case; |
4840 | 4838 |
4841 if (FLAG_debug_code) { | 4839 if (FLAG_debug_code) { |
4842 __ CompareRoot(value_reg, Heap::kTheHoleValueRootIndex); | 4840 __ CompareRoot(value_reg, Heap::kTheHoleValueRootIndex); |
4843 __ Check(not_equal, kUnexpectedValue); | 4841 __ Check(not_equal, kUnexpectedValue); |
4844 __ AssertName(name_reg); | |
4845 } | 4842 } |
4846 | 4843 |
4847 // Go up context chain to the script context. | 4844 // Go up context chain to the script context. |
4848 for (int i = 0; i < depth(); ++i) { | 4845 for (int i = 0; i < depth(); ++i) { |
4849 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 4846 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
4850 context_reg = cell_reg; | 4847 context_reg = cell_reg; |
4851 } | 4848 } |
4852 | 4849 |
4853 // Load the PropertyCell at the specified slot. | 4850 // Load the PropertyCell at the specified slot. |
4854 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); | 4851 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); |
(...skipping 30 matching lines...) Expand all Loading... |
4885 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 4882 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
4886 OMIT_SMI_CHECK); | 4883 OMIT_SMI_CHECK); |
4887 // RecordWriteField clobbers the value register, so we need to reload. | 4884 // RecordWriteField clobbers the value register, so we need to reload. |
4888 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 4885 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
4889 __ Ret(); | 4886 __ Ret(); |
4890 __ bind(¬_mutable_data); | 4887 __ bind(¬_mutable_data); |
4891 | 4888 |
4892 // Check if PropertyCell value matches the new value (relevant for Constant, | 4889 // Check if PropertyCell value matches the new value (relevant for Constant, |
4893 // ConstantType and Undefined cells). | 4890 // ConstantType and Undefined cells). |
4894 Label not_same_value; | 4891 Label not_same_value; |
4895 __ cmp(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 4892 __ mov(cell_value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
| 4893 __ cmp(cell_value_reg, value_reg); |
4896 __ j(not_equal, ¬_same_value, | 4894 __ j(not_equal, ¬_same_value, |
4897 FLAG_debug_code ? Label::kFar : Label::kNear); | 4895 FLAG_debug_code ? Label::kFar : Label::kNear); |
4898 if (FLAG_debug_code) { | 4896 if (FLAG_debug_code) { |
4899 Label done; | 4897 Label done; |
4900 // This can only be true for Constant, ConstantType and Undefined cells, | 4898 // This can only be true for Constant, ConstantType and Undefined cells, |
4901 // because we never store the_hole via this stub. | 4899 // because we never store the_hole via this stub. |
4902 __ cmp(cell_details_reg, | 4900 __ cmp(cell_details_reg, |
4903 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4901 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4904 PropertyCellType::kConstant) | | 4902 PropertyCellType::kConstant) | |
4905 PropertyDetails::KindField::encode(kData))); | 4903 PropertyDetails::KindField::encode(kData))); |
(...skipping 16 matching lines...) Expand all Loading... |
4922 // Check if PropertyCell contains data with constant type. | 4920 // Check if PropertyCell contains data with constant type. |
4923 __ cmp(cell_details_reg, | 4921 __ cmp(cell_details_reg, |
4924 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4922 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4925 PropertyCellType::kConstantType) | | 4923 PropertyCellType::kConstantType) | |
4926 PropertyDetails::KindField::encode(kData))); | 4924 PropertyDetails::KindField::encode(kData))); |
4927 __ j(not_equal, &slow_case, Label::kNear); | 4925 __ j(not_equal, &slow_case, Label::kNear); |
4928 | 4926 |
4929 // Now either both old and new values must be SMIs or both must be heap | 4927 // Now either both old and new values must be SMIs or both must be heap |
4930 // objects with same map. | 4928 // objects with same map. |
4931 Label value_is_heap_object; | 4929 Label value_is_heap_object; |
4932 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. | |
4933 Register cell_value_reg = cell_details_reg; | |
4934 __ mov(cell_value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | |
4935 __ JumpIfNotSmi(value_reg, &value_is_heap_object, Label::kNear); | 4930 __ JumpIfNotSmi(value_reg, &value_is_heap_object, Label::kNear); |
4936 __ JumpIfNotSmi(cell_value_reg, &slow_case, Label::kNear); | 4931 __ JumpIfNotSmi(cell_value_reg, &slow_case, Label::kNear); |
4937 // Old and new values are SMIs, no need for a write barrier here. | 4932 // Old and new values are SMIs, no need for a write barrier here. |
4938 __ bind(&fast_smi_case); | 4933 __ bind(&fast_smi_case); |
4939 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); | 4934 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); |
4940 __ Ret(); | 4935 __ Ret(); |
4941 __ bind(&value_is_heap_object); | 4936 __ bind(&value_is_heap_object); |
4942 __ JumpIfSmi(cell_value_reg, &slow_case, Label::kNear); | 4937 __ JumpIfSmi(cell_value_reg, &slow_case, Label::kNear); |
4943 Register cell_value_map_reg = cell_value_reg; | 4938 Register cell_value_map_reg = cell_value_reg; |
4944 __ mov(cell_value_map_reg, | 4939 __ mov(cell_value_map_reg, |
4945 FieldOperand(cell_value_reg, HeapObject::kMapOffset)); | 4940 FieldOperand(cell_value_reg, HeapObject::kMapOffset)); |
4946 __ cmp(cell_value_map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); | 4941 __ cmp(cell_value_map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); |
4947 __ j(equal, &fast_heapobject_case); | 4942 __ j(equal, &fast_heapobject_case); |
4948 | 4943 |
4949 // Fallback to the runtime. | 4944 // Fallback to the runtime. |
4950 __ bind(&slow_case); | 4945 __ bind(&slow_case); |
4951 __ SmiTag(slot_reg); | 4946 __ SmiTag(slot_reg); |
4952 __ Pop(cell_reg); // Pop return address. | 4947 __ Pop(cell_reg); // Pop return address. |
4953 __ Push(slot_reg); | 4948 __ Push(slot_reg); |
4954 __ Push(name_reg); | |
4955 __ Push(value_reg); | 4949 __ Push(value_reg); |
4956 __ Push(cell_reg); // Push return address. | 4950 __ Push(cell_reg); // Push return address. |
4957 __ TailCallRuntime(is_strict(language_mode()) | 4951 __ TailCallRuntime(is_strict(language_mode()) |
4958 ? Runtime::kStoreGlobalViaContext_Strict | 4952 ? Runtime::kStoreGlobalViaContext_Strict |
4959 : Runtime::kStoreGlobalViaContext_Sloppy, | 4953 : Runtime::kStoreGlobalViaContext_Sloppy, |
4960 3, 1); | 4954 2, 1); |
4961 } | 4955 } |
4962 | 4956 |
4963 | 4957 |
4964 // Generates an Operand for saving parameters after PrepareCallApiFunction. | 4958 // Generates an Operand for saving parameters after PrepareCallApiFunction. |
4965 static Operand ApiParameterOperand(int index) { | 4959 static Operand ApiParameterOperand(int index) { |
4966 return Operand(esp, index * kPointerSize); | 4960 return Operand(esp, index * kPointerSize); |
4967 } | 4961 } |
4968 | 4962 |
4969 | 4963 |
4970 // Prepares stack to put arguments (aligns and so on). Reserves | 4964 // Prepares stack to put arguments (aligns and so on). Reserves |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5344 Operand(ebp, 7 * kPointerSize), NULL); | 5338 Operand(ebp, 7 * kPointerSize), NULL); |
5345 } | 5339 } |
5346 | 5340 |
5347 | 5341 |
5348 #undef __ | 5342 #undef __ |
5349 | 5343 |
5350 } // namespace internal | 5344 } // namespace internal |
5351 } // namespace v8 | 5345 } // namespace v8 |
5352 | 5346 |
5353 #endif // V8_TARGET_ARCH_X87 | 5347 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |