| 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 |