| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 5155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5166 | 5166 |
| 5167 // Go up context chain to the script context. | 5167 // Go up context chain to the script context. |
| 5168 for (int i = 0; i < depth(); ++i) { | 5168 for (int i = 0; i < depth(); ++i) { |
| 5169 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 5169 __ mov(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
| 5170 context_reg = cell_reg; | 5170 context_reg = cell_reg; |
| 5171 } | 5171 } |
| 5172 | 5172 |
| 5173 // Load the PropertyCell at the specified slot. | 5173 // Load the PropertyCell at the specified slot. |
| 5174 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); | 5174 __ mov(cell_reg, ContextOperand(context_reg, slot_reg)); |
| 5175 | 5175 |
| 5176 // Check that cell value is not the_hole. | |
| 5177 { | |
| 5178 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. | |
| 5179 Register cell_value_reg = cell_details_reg; | |
| 5180 __ mov(cell_value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | |
| 5181 __ CompareRoot(cell_value_reg, Heap::kTheHoleValueRootIndex); | |
| 5182 __ j(equal, &slow_case, FLAG_debug_code ? Label::kFar : Label::kNear); | |
| 5183 } | |
| 5184 | |
| 5185 // Load PropertyDetails for the cell (actually only the cell_type and kind). | 5176 // Load PropertyDetails for the cell (actually only the cell_type and kind). |
| 5186 __ mov(cell_details_reg, | 5177 __ mov(cell_details_reg, |
| 5187 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); | 5178 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); |
| 5188 __ SmiUntag(cell_details_reg); | 5179 __ SmiUntag(cell_details_reg); |
| 5189 __ and_(cell_details_reg, | 5180 __ and_(cell_details_reg, |
| 5190 Immediate(PropertyDetails::PropertyCellTypeField::kMask | | 5181 Immediate(PropertyDetails::PropertyCellTypeField::kMask | |
| 5191 PropertyDetails::KindField::kMask)); | 5182 PropertyDetails::KindField::kMask | |
| 5192 | 5183 PropertyDetails::kAttributesReadOnlyMask)); |
| 5193 | 5184 |
| 5194 // Check if PropertyCell holds mutable data. | 5185 // Check if PropertyCell holds mutable data. |
| 5195 Label not_mutable_data; | 5186 Label not_mutable_data; |
| 5196 __ cmp(cell_details_reg, | 5187 __ cmp(cell_details_reg, |
| 5197 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5188 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
| 5198 PropertyCellType::kMutable) | | 5189 PropertyCellType::kMutable) | |
| 5199 PropertyDetails::KindField::encode(kData))); | 5190 PropertyDetails::KindField::encode(kData))); |
| 5200 __ j(not_equal, ¬_mutable_data); | 5191 __ j(not_equal, ¬_mutable_data); |
| 5201 __ JumpIfSmi(value_reg, &fast_smi_case); | 5192 __ JumpIfSmi(value_reg, &fast_smi_case); |
| 5202 __ bind(&fast_heapobject_case); | 5193 __ bind(&fast_heapobject_case); |
| 5203 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); | 5194 __ mov(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); |
| 5204 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg, | 5195 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg, |
| 5205 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 5196 cell_details_reg, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
| 5206 OMIT_SMI_CHECK); | 5197 OMIT_SMI_CHECK); |
| 5207 // RecordWriteField clobbers the value register, so we need to reload. | 5198 // RecordWriteField clobbers the value register, so we need to reload. |
| 5208 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 5199 __ mov(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
| 5209 __ Ret(); | 5200 __ Ret(); |
| 5210 __ bind(¬_mutable_data); | 5201 __ bind(¬_mutable_data); |
| 5211 | 5202 |
| 5212 // Check if PropertyCell value matches the new value (relevant for Constant, | 5203 // Check if PropertyCell value matches the new value (relevant for Constant, |
| 5213 // ConstantType and Undefined cells). | 5204 // ConstantType and Undefined cells). |
| 5214 Label not_same_value; | 5205 Label not_same_value; |
| 5215 __ cmp(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); | 5206 __ cmp(value_reg, FieldOperand(cell_reg, PropertyCell::kValueOffset)); |
| 5216 __ j(not_equal, ¬_same_value, | 5207 __ j(not_equal, ¬_same_value, |
| 5217 FLAG_debug_code ? Label::kFar : Label::kNear); | 5208 FLAG_debug_code ? Label::kFar : Label::kNear); |
| 5209 // Make sure the PropertyCell is not marked READ_ONLY. |
| 5210 __ test(cell_details_reg, |
| 5211 Immediate(PropertyDetails::kAttributesReadOnlyMask)); |
| 5212 __ j(not_zero, &slow_case); |
| 5218 if (FLAG_debug_code) { | 5213 if (FLAG_debug_code) { |
| 5219 Label done; | 5214 Label done; |
| 5220 // This can only be true for Constant, ConstantType and Undefined cells, | 5215 // This can only be true for Constant, ConstantType and Undefined cells, |
| 5221 // because we never store the_hole via this stub. | 5216 // because we never store the_hole via this stub. |
| 5222 __ cmp(cell_details_reg, | 5217 __ cmp(cell_details_reg, |
| 5223 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5218 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
| 5224 PropertyCellType::kConstant) | | 5219 PropertyCellType::kConstant) | |
| 5225 PropertyDetails::KindField::encode(kData))); | 5220 PropertyDetails::KindField::encode(kData))); |
| 5226 __ j(equal, &done); | 5221 __ j(equal, &done); |
| 5227 __ cmp(cell_details_reg, | 5222 __ cmp(cell_details_reg, |
| 5228 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5223 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
| 5229 PropertyCellType::kConstantType) | | 5224 PropertyCellType::kConstantType) | |
| 5230 PropertyDetails::KindField::encode(kData))); | 5225 PropertyDetails::KindField::encode(kData))); |
| 5231 __ j(equal, &done); | 5226 __ j(equal, &done); |
| 5232 __ cmp(cell_details_reg, | 5227 __ cmp(cell_details_reg, |
| 5233 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5228 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
| 5234 PropertyCellType::kUndefined) | | 5229 PropertyCellType::kUndefined) | |
| 5235 PropertyDetails::KindField::encode(kData))); | 5230 PropertyDetails::KindField::encode(kData))); |
| 5236 __ Check(equal, kUnexpectedValue); | 5231 __ Check(equal, kUnexpectedValue); |
| 5237 __ bind(&done); | 5232 __ bind(&done); |
| 5238 } | 5233 } |
| 5239 __ Ret(); | 5234 __ Ret(); |
| 5240 __ bind(¬_same_value); | 5235 __ bind(¬_same_value); |
| 5241 | 5236 |
| 5242 // Check if PropertyCell contains data with constant type. | 5237 // Check if PropertyCell contains data with constant type (and is not |
| 5238 // READ_ONLY). |
| 5243 __ cmp(cell_details_reg, | 5239 __ cmp(cell_details_reg, |
| 5244 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5240 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
| 5245 PropertyCellType::kConstantType) | | 5241 PropertyCellType::kConstantType) | |
| 5246 PropertyDetails::KindField::encode(kData))); | 5242 PropertyDetails::KindField::encode(kData))); |
| 5247 __ j(not_equal, &slow_case, Label::kNear); | 5243 __ j(not_equal, &slow_case, Label::kNear); |
| 5248 | 5244 |
| 5249 // Now either both old and new values must be SMIs or both must be heap | 5245 // Now either both old and new values must be SMIs or both must be heap |
| 5250 // objects with same map. | 5246 // objects with same map. |
| 5251 Label value_is_heap_object; | 5247 Label value_is_heap_object; |
| 5252 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. | 5248 // TODO(bmeurer): use ecx (name_reg) when name parameter is removed. |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5664 Operand(ebp, 7 * kPointerSize), NULL); | 5660 Operand(ebp, 7 * kPointerSize), NULL); |
| 5665 } | 5661 } |
| 5666 | 5662 |
| 5667 | 5663 |
| 5668 #undef __ | 5664 #undef __ |
| 5669 | 5665 |
| 5670 } // namespace internal | 5666 } // namespace internal |
| 5671 } // namespace v8 | 5667 } // namespace v8 |
| 5672 | 5668 |
| 5673 #endif // V8_TARGET_ARCH_IA32 | 5669 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |