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 |