| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 | 1176 |
| 1177 | 1177 |
| 1178 int HeapNumber::get_sign() { | 1178 int HeapNumber::get_sign() { |
| 1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; | 1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; |
| 1180 } | 1180 } |
| 1181 | 1181 |
| 1182 | 1182 |
| 1183 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) | 1183 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
| 1184 | 1184 |
| 1185 | 1185 |
| 1186 Object** FixedArray::GetFirstElementAddress() { |
| 1187 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0))); |
| 1188 } |
| 1189 |
| 1190 |
| 1191 bool FixedArray::ContainsOnlySmisOrHoles() { |
| 1192 Object* the_hole = GetHeap()->the_hole_value(); |
| 1193 Object** current = GetFirstElementAddress(); |
| 1194 for (int i = 0; i < length(); ++i) { |
| 1195 Object* candidate = *current++; |
| 1196 if (!candidate->IsSmi() && candidate != the_hole) return false; |
| 1197 } |
| 1198 return true; |
| 1199 } |
| 1200 |
| 1201 |
| 1186 FixedArrayBase* JSObject::elements() { | 1202 FixedArrayBase* JSObject::elements() { |
| 1187 Object* array = READ_FIELD(this, kElementsOffset); | 1203 Object* array = READ_FIELD(this, kElementsOffset); |
| 1188 return static_cast<FixedArrayBase*>(array); | 1204 return static_cast<FixedArrayBase*>(array); |
| 1189 } | 1205 } |
| 1190 | 1206 |
| 1191 void JSObject::ValidateSmiOnlyElements() { | 1207 void JSObject::ValidateSmiOnlyElements() { |
| 1192 #if DEBUG | 1208 #if DEBUG |
| 1193 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | 1209 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { |
| 1194 Heap* heap = GetHeap(); | 1210 Heap* heap = GetHeap(); |
| 1195 // Don't use elements, since integrity checks will fail if there | 1211 // Don't use elements, since integrity checks will fail if there |
| 1196 // are filler pointers in the array. | 1212 // are filler pointers in the array. |
| 1197 FixedArray* fixed_array = | 1213 FixedArray* fixed_array = |
| 1198 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset)); | 1214 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset)); |
| 1199 Map* map = fixed_array->map(); | 1215 Map* map = fixed_array->map(); |
| 1200 // Arrays that have been shifted in place can't be verified. | 1216 // Arrays that have been shifted in place can't be verified. |
| 1201 if (map != heap->raw_unchecked_one_pointer_filler_map() && | 1217 if (map != heap->raw_unchecked_one_pointer_filler_map() && |
| 1202 map != heap->raw_unchecked_two_pointer_filler_map() && | 1218 map != heap->raw_unchecked_two_pointer_filler_map() && |
| 1203 map != heap->free_space_map()) { | 1219 map != heap->free_space_map()) { |
| 1204 for (int i = 0; i < fixed_array->length(); i++) { | 1220 for (int i = 0; i < fixed_array->length(); i++) { |
| 1205 Object* current = fixed_array->get(i); | 1221 Object* current = fixed_array->get(i); |
| 1206 ASSERT(current->IsSmi() || current == heap->the_hole_value()); | 1222 ASSERT(current->IsSmi() || current == heap->the_hole_value()); |
| 1207 } | 1223 } |
| 1208 } | 1224 } |
| 1209 } | 1225 } |
| 1210 #endif | 1226 #endif |
| 1211 } | 1227 } |
| 1212 | 1228 |
| 1213 | 1229 |
| 1214 MaybeObject* JSObject::EnsureCanContainNonSmiElements() { | 1230 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { |
| 1215 #if DEBUG | 1231 #if DEBUG |
| 1216 ValidateSmiOnlyElements(); | 1232 ValidateSmiOnlyElements(); |
| 1217 #endif | 1233 #endif |
| 1218 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) { | 1234 if ((map()->elements_kind() != FAST_ELEMENTS)) { |
| 1219 Object* obj; | 1235 return TransitionElementsKind(FAST_ELEMENTS); |
| 1220 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); | |
| 1221 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 1222 set_map(Map::cast(obj)); | |
| 1223 } | 1236 } |
| 1224 return this; | 1237 return this; |
| 1225 } | 1238 } |
| 1226 | 1239 |
| 1227 | 1240 |
| 1228 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, | 1241 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, |
| 1229 uint32_t count) { | 1242 uint32_t count, |
| 1230 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | 1243 EnsureElementsMode mode) { |
| 1231 for (uint32_t i = 0; i < count; ++i) { | 1244 ElementsKind current_kind = map()->elements_kind(); |
| 1232 Object* current = *objects++; | 1245 ElementsKind target_kind = current_kind; |
| 1233 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) { | 1246 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 1234 return EnsureCanContainNonSmiElements(); | 1247 if (current_kind == FAST_ELEMENTS) return this; |
| 1248 |
| 1249 Heap* heap = GetHeap(); |
| 1250 Object* the_hole = heap->the_hole_value(); |
| 1251 Object* heap_number_map = heap->heap_number_map(); |
| 1252 for (uint32_t i = 0; i < count; ++i) { |
| 1253 Object* current = *objects++; |
| 1254 if (!current->IsSmi() && current != the_hole) { |
| 1255 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && |
| 1256 HeapObject::cast(current)->map() == heap_number_map) { |
| 1257 target_kind = FAST_DOUBLE_ELEMENTS; |
| 1258 } else { |
| 1259 target_kind = FAST_ELEMENTS; |
| 1260 break; |
| 1235 } | 1261 } |
| 1236 } | 1262 } |
| 1237 } | 1263 } |
| 1264 |
| 1265 if (target_kind != current_kind) { |
| 1266 return TransitionElementsKind(target_kind); |
| 1267 } |
| 1238 return this; | 1268 return this; |
| 1239 } | 1269 } |
| 1240 | 1270 |
| 1241 | 1271 |
| 1242 MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) { | 1272 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, |
| 1243 Object** objects = reinterpret_cast<Object**>( | 1273 EnsureElementsMode mode) { |
| 1244 FIELD_ADDR(elements, elements->OffsetOfElementAt(0))); | 1274 if (elements->map() != GetHeap()->fixed_double_array_map()) { |
| 1245 return EnsureCanContainElements(objects, elements->length()); | 1275 ASSERT(elements->map() == GetHeap()->fixed_array_map() || |
| 1276 elements->map() == GetHeap()->fixed_cow_array_map()); |
| 1277 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { |
| 1278 mode = DONT_ALLOW_DOUBLE_ELEMENTS; |
| 1279 } |
| 1280 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); |
| 1281 return EnsureCanContainElements(objects, elements->length(), mode); |
| 1282 } |
| 1283 |
| 1284 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 1285 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { |
| 1286 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); |
| 1287 } |
| 1288 |
| 1289 return this; |
| 1246 } | 1290 } |
| 1247 | 1291 |
| 1248 | 1292 |
| 1249 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { | 1293 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { |
| 1250 ASSERT((map()->has_fast_elements() || | 1294 ASSERT((map()->has_fast_elements() || |
| 1251 map()->has_fast_smi_only_elements()) == | 1295 map()->has_fast_smi_only_elements()) == |
| 1252 (value->map() == GetHeap()->fixed_array_map() || | 1296 (value->map() == GetHeap()->fixed_array_map() || |
| 1253 value->map() == GetHeap()->fixed_cow_array_map())); | 1297 value->map() == GetHeap()->fixed_cow_array_map())); |
| 1254 ASSERT(map()->has_fast_double_elements() == | 1298 ASSERT(map()->has_fast_double_elements() == |
| 1255 value->IsFixedDoubleArray()); | 1299 value->IsFixedDoubleArray()); |
| (...skipping 2857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4113 ElementsKind JSObject::GetElementsKind() { | 4157 ElementsKind JSObject::GetElementsKind() { |
| 4114 ElementsKind kind = map()->elements_kind(); | 4158 ElementsKind kind = map()->elements_kind(); |
| 4115 #if DEBUG | 4159 #if DEBUG |
| 4116 FixedArrayBase* fixed_array = | 4160 FixedArrayBase* fixed_array = |
| 4117 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); | 4161 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); |
| 4118 Map* map = fixed_array->map(); | 4162 Map* map = fixed_array->map(); |
| 4119 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && | 4163 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && |
| 4120 (map == GetHeap()->fixed_array_map() || | 4164 (map == GetHeap()->fixed_array_map() || |
| 4121 map == GetHeap()->fixed_cow_array_map())) || | 4165 map == GetHeap()->fixed_cow_array_map())) || |
| 4122 (kind == FAST_DOUBLE_ELEMENTS && | 4166 (kind == FAST_DOUBLE_ELEMENTS && |
| 4123 fixed_array->IsFixedDoubleArray()) || | 4167 (fixed_array->IsFixedDoubleArray() || |
| 4168 fixed_array == GetHeap()->empty_fixed_array())) || |
| 4124 (kind == DICTIONARY_ELEMENTS && | 4169 (kind == DICTIONARY_ELEMENTS && |
| 4125 fixed_array->IsFixedArray() && | 4170 fixed_array->IsFixedArray() && |
| 4126 fixed_array->IsDictionary()) || | 4171 fixed_array->IsDictionary()) || |
| 4127 (kind > DICTIONARY_ELEMENTS)); | 4172 (kind > DICTIONARY_ELEMENTS)); |
| 4128 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || | 4173 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || |
| 4129 (elements()->IsFixedArray() && elements()->length() >= 2)); | 4174 (elements()->IsFixedArray() && elements()->length() >= 2)); |
| 4130 #endif | 4175 #endif |
| 4131 return kind; | 4176 return kind; |
| 4132 } | 4177 } |
| 4133 | 4178 |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4572 } | 4617 } |
| 4573 } | 4618 } |
| 4574 | 4619 |
| 4575 | 4620 |
| 4576 void JSArray::set_length(Smi* length) { | 4621 void JSArray::set_length(Smi* length) { |
| 4577 // Don't need a write barrier for a Smi. | 4622 // Don't need a write barrier for a Smi. |
| 4578 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); | 4623 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); |
| 4579 } | 4624 } |
| 4580 | 4625 |
| 4581 | 4626 |
| 4582 MaybeObject* JSArray::SetContent(FixedArray* storage) { | 4627 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { |
| 4583 MaybeObject* maybe_object = EnsureCanContainElements(storage); | 4628 MaybeObject* maybe_result = EnsureCanContainElements( |
| 4584 if (maybe_object->IsFailure()) return maybe_object; | 4629 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 4630 if (maybe_result->IsFailure()) return maybe_result; |
| 4631 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && |
| 4632 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || |
| 4633 ((storage->map() != GetHeap()->fixed_double_array_map()) && |
| 4634 ((GetElementsKind() == FAST_ELEMENTS) || |
| 4635 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && |
| 4636 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); |
| 4637 set_elements(storage); |
| 4585 set_length(Smi::FromInt(storage->length())); | 4638 set_length(Smi::FromInt(storage->length())); |
| 4586 set_elements(storage); | |
| 4587 return this; | 4639 return this; |
| 4588 } | 4640 } |
| 4589 | 4641 |
| 4590 | 4642 |
| 4591 MaybeObject* FixedArray::Copy() { | 4643 MaybeObject* FixedArray::Copy() { |
| 4592 if (length() == 0) return this; | 4644 if (length() == 0) return this; |
| 4593 return GetHeap()->CopyFixedArray(this); | 4645 return GetHeap()->CopyFixedArray(this); |
| 4594 } | 4646 } |
| 4595 | 4647 |
| 4596 | 4648 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4700 #undef WRITE_INT_FIELD | 4752 #undef WRITE_INT_FIELD |
| 4701 #undef READ_SHORT_FIELD | 4753 #undef READ_SHORT_FIELD |
| 4702 #undef WRITE_SHORT_FIELD | 4754 #undef WRITE_SHORT_FIELD |
| 4703 #undef READ_BYTE_FIELD | 4755 #undef READ_BYTE_FIELD |
| 4704 #undef WRITE_BYTE_FIELD | 4756 #undef WRITE_BYTE_FIELD |
| 4705 | 4757 |
| 4706 | 4758 |
| 4707 } } // namespace v8::internal | 4759 } } // namespace v8::internal |
| 4708 | 4760 |
| 4709 #endif // V8_OBJECTS_INL_H_ | 4761 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |