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 4835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4846 | 4846 |
4847 // Go up context chain to the script context. | 4847 // Go up context chain to the script context. |
4848 for (int i = 0; i < depth(); ++i) { | 4848 for (int i = 0; i < depth(); ++i) { |
4849 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 4849 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
4850 context_reg = cell_reg; | 4850 context_reg = cell_reg; |
4851 } | 4851 } |
4852 | 4852 |
4853 // Load the PropertyCell at the specified slot. | 4853 // Load the PropertyCell at the specified slot. |
4854 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); | 4854 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); |
4855 | 4855 |
4856 // Check that cell value is not the_hole. | |
4857 { | |
4858 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. | |
4859 Register cell_value_reg = cell_details_reg; | |
4860 __ mov(cell_value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | |
4861 __ CompareRoot(cell_value_reg, Heap::kTheHoleValueRootIndex); | |
4862 __ j(equal, &slow_case, FLAG_debug_code ? Label::kFar : Label::kNear); | |
4863 } | |
4864 | |
4865 // Load PropertyDetails for the cell (actually only the cell_type and kind). | 4856 // Load PropertyDetails for the cell (actually only the cell_type and kind). |
4866 __ mov(cell_details_reg, | 4857 __ mov(cell_details_reg, |
4867 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); | 4858 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); |
4868 __ SmiUntag(cell_details_reg); | 4859 __ SmiUntag(cell_details_reg); |
4869 __ and_(cell_details_reg, | 4860 __ and_(cell_details_reg, |
4870 Immediate(PropertyDetails::PropertyCellTypeField::kMask | | 4861 Immediate(PropertyDetails::PropertyCellTypeField::kMask | |
4871 PropertyDetails::KindField::kMask)); | 4862 PropertyDetails::KindField::kMask | |
4872 | 4863 PropertyDetails::kAttributesReadOnlyMask)); |
4873 | 4864 |
4874 // Check if PropertyCell holds mutable data. | 4865 // Check if PropertyCell holds mutable data. |
4875 Label not_mutable_data; | 4866 Label not_mutable_data; |
4876 __ cmp(cell_details_reg, | 4867 __ cmp(cell_details_reg, |
4877 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4868 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4878 PropertyCellType::kMutable) | | 4869 PropertyCellType::kMutable) | |
4879 PropertyDetails::KindField::encode(kData))); | 4870 PropertyDetails::KindField::encode(kData))); |
4880 __ j(not_equal, ¬_mutable_data); | 4871 __ j(not_equal, ¬_mutable_data); |
4881 __ JumpIfSmi(value_reg, &fast_smi_case); | 4872 __ JumpIfSmi(value_reg, &fast_smi_case); |
4882 __ bind(&fast_heapobject_case); | 4873 __ bind(&fast_heapobject_case); |
4883 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); | 4874 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); |
4884 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg, | 4875 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg, |
4885 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 4876 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
4886 OMIT_SMI_CHECK); | 4877 OMIT_SMI_CHECK); |
4887 // RecordWriteField clobbers the value register, so we need to reload. | 4878 // RecordWriteField clobbers the value register, so we need to reload. |
4888 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 4879 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
4889 __ Ret(); | 4880 __ Ret(); |
4890 __ bind(¬_mutable_data); | 4881 __ bind(¬_mutable_data); |
4891 | 4882 |
4892 // Check if PropertyCell value matches the new value (relevant for Constant, | 4883 // Check if PropertyCell value matches the new value (relevant for Constant, |
4893 // ConstantType and Undefined cells). | 4884 // ConstantType and Undefined cells). |
4894 Label not_same_value; | 4885 Label not_same_value; |
4895 __ cmp(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 4886 __ cmp(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
4896 __ j(not_equal, ¬_same_value, | 4887 __ j(not_equal, ¬_same_value, |
4897 FLAG_debug_code ? Label::kFar : Label::kNear); | 4888 FLAG_debug_code ? Label::kFar : Label::kNear); |
| 4889 // Make sure the PropertyCell is not marked READ_ONLY. |
| 4890 __ test(cell_details_reg, |
| 4891 Immediate(PropertyDetails::kAttributesReadOnlyMask)); |
| 4892 __ j(not_zero, &slow_case); |
4898 if (FLAG_debug_code) { | 4893 if (FLAG_debug_code) { |
4899 Label done; | 4894 Label done; |
4900 // This can only be true for Constant, ConstantType and Undefined cells, | 4895 // This can only be true for Constant, ConstantType and Undefined cells, |
4901 // because we never store the_hole via this stub. | 4896 // because we never store the_hole via this stub. |
4902 __ cmp(cell_details_reg, | 4897 __ cmp(cell_details_reg, |
4903 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4898 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4904 PropertyCellType::kConstant) | | 4899 PropertyCellType::kConstant) | |
4905 PropertyDetails::KindField::encode(kData))); | 4900 PropertyDetails::KindField::encode(kData))); |
4906 __ j(equal, &done); | 4901 __ j(equal, &done); |
4907 __ cmp(cell_details_reg, | 4902 __ cmp(cell_details_reg, |
4908 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4903 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4909 PropertyCellType::kConstantType) | | 4904 PropertyCellType::kConstantType) | |
4910 PropertyDetails::KindField::encode(kData))); | 4905 PropertyDetails::KindField::encode(kData))); |
4911 __ j(equal, &done); | 4906 __ j(equal, &done); |
4912 __ cmp(cell_details_reg, | 4907 __ cmp(cell_details_reg, |
4913 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4908 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4914 PropertyCellType::kUndefined) | | 4909 PropertyCellType::kUndefined) | |
4915 PropertyDetails::KindField::encode(kData))); | 4910 PropertyDetails::KindField::encode(kData))); |
4916 __ Check(equal, kUnexpectedValue); | 4911 __ Check(equal, kUnexpectedValue); |
4917 __ bind(&done); | 4912 __ bind(&done); |
4918 } | 4913 } |
4919 __ Ret(); | 4914 __ Ret(); |
4920 __ bind(¬_same_value); | 4915 __ bind(¬_same_value); |
4921 | 4916 |
4922 // Check if PropertyCell contains data with constant type. | 4917 // Check if PropertyCell contains data with constant type (and is not |
| 4918 // READ_ONLY). |
4923 __ cmp(cell_details_reg, | 4919 __ cmp(cell_details_reg, |
4924 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 4920 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
4925 PropertyCellType::kConstantType) | | 4921 PropertyCellType::kConstantType) | |
4926 PropertyDetails::KindField::encode(kData))); | 4922 PropertyDetails::KindField::encode(kData))); |
4927 __ j(not_equal, &slow_case, Label::kNear); | 4923 __ j(not_equal, &slow_case, Label::kNear); |
4928 | 4924 |
4929 // Now either both old and new values must be SMIs or both must be heap | 4925 // Now either both old and new values must be SMIs or both must be heap |
4930 // objects with same map. | 4926 // objects with same map. |
4931 Label value_is_heap_object; | 4927 Label value_is_heap_object; |
4932 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. | 4928 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5344 Operand(ebp, 7 * kPointerSize), NULL); | 5340 Operand(ebp, 7 * kPointerSize), NULL); |
5345 } | 5341 } |
5346 | 5342 |
5347 | 5343 |
5348 #undef __ | 5344 #undef __ |
5349 | 5345 |
5350 } // namespace internal | 5346 } // namespace internal |
5351 } // namespace v8 | 5347 } // namespace v8 |
5352 | 5348 |
5353 #endif // V8_TARGET_ARCH_X87 | 5349 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |