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 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1394 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) | 1394 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
1395 | 1395 |
1396 | 1396 |
1397 FixedArrayBase* JSObject::elements() { | 1397 FixedArrayBase* JSObject::elements() { |
1398 Object* array = READ_FIELD(this, kElementsOffset); | 1398 Object* array = READ_FIELD(this, kElementsOffset); |
1399 ASSERT(array->HasValidElements()); | 1399 ASSERT(array->HasValidElements()); |
1400 return static_cast<FixedArrayBase*>(array); | 1400 return static_cast<FixedArrayBase*>(array); |
1401 } | 1401 } |
1402 | 1402 |
1403 | 1403 |
1404 MaybeObject* JSObject::EnsureCanContainNonSmiElements() { | |
1405 if (FLAG_smi_only_arrays && | |
1406 (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) { | |
1407 #ifdef DEBUG | |
1408 Heap* heap = GetHeap(); | |
1409 FixedArray* fixed_array = FixedArray::cast(elements()); | |
1410 for (int i = 0; i < fixed_array->length(); i++) { | |
1411 Object* current = fixed_array->get(i); | |
1412 ASSERT(current->IsSmi() || current == heap->the_hole_value()); | |
1413 } | |
1414 #endif | |
1415 Object* obj; | |
1416 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); | |
1417 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
1418 set_map(Map::cast(obj)); | |
1419 } | |
1420 return this; | |
1421 } | |
1422 | |
1423 | |
1424 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, | |
1425 uint32_t count) { | |
1426 if (FLAG_smi_only_arrays && | |
1427 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | |
1428 for (uint32_t i = 0; i < count; ++i) { | |
1429 Object* current = *objects++; | |
1430 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) { | |
1431 return EnsureCanContainNonSmiElements(); | |
1432 } | |
1433 } | |
1434 } | |
1435 return this; | |
1436 } | |
1437 | |
1438 | |
1439 MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) { | |
1440 if (FLAG_smi_only_arrays) { | |
1441 Object** objects = reinterpret_cast<Object**>( | |
1442 FIELD_ADDR(elements, elements->OffsetOfElementAt(0))); | |
1443 return EnsureCanContainElements(objects, elements->length()); | |
1444 } else { | |
1445 return this; | |
1446 } | |
1447 } | |
1448 | |
1449 | |
1404 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { | 1450 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { |
1405 ASSERT(map()->has_fast_elements() == | 1451 ASSERT((map()->has_fast_elements() || |
1452 map()->has_fast_smi_only_elements()) == | |
1406 (value->map() == GetHeap()->fixed_array_map() || | 1453 (value->map() == GetHeap()->fixed_array_map() || |
1407 value->map() == GetHeap()->fixed_cow_array_map())); | 1454 value->map() == GetHeap()->fixed_cow_array_map())); |
1408 ASSERT(map()->has_fast_double_elements() == | 1455 ASSERT(map()->has_fast_double_elements() == |
1409 value->IsFixedDoubleArray()); | 1456 value->IsFixedDoubleArray()); |
1410 ASSERT(value->HasValidElements()); | 1457 ASSERT(value->HasValidElements()); |
1458 #ifdef DEBUG | |
1459 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | |
1460 Heap* heap = GetHeap(); | |
Sven Panne
2011/09/16 09:19:32
Copy-n-paste from above, perhaps introduce a helpe
danno
2011/09/21 14:32:04
Done.
| |
1461 for (int i = 0; i < value->length(); i++) { | |
1462 Object* current = FixedArray::cast(value)->get(i); | |
1463 ASSERT(current->IsSmi() || current == heap->the_hole_value()); | |
1464 } | |
1465 } | |
1466 #endif | |
1411 WRITE_FIELD(this, kElementsOffset, value); | 1467 WRITE_FIELD(this, kElementsOffset, value); |
1412 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode); | 1468 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode); |
1413 } | 1469 } |
1414 | 1470 |
1415 | 1471 |
1416 void JSObject::initialize_properties() { | 1472 void JSObject::initialize_properties() { |
1417 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1473 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
1418 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); | 1474 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); |
1419 } | 1475 } |
1420 | 1476 |
1421 | 1477 |
1422 void JSObject::initialize_elements() { | 1478 void JSObject::initialize_elements() { |
1423 ASSERT(map()->has_fast_elements()); | 1479 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements()); |
1424 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1480 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
1425 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); | 1481 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); |
1426 } | 1482 } |
1427 | 1483 |
1428 | 1484 |
1429 MaybeObject* JSObject::ResetElements() { | 1485 MaybeObject* JSObject::ResetElements() { |
1430 Object* obj; | 1486 Object* obj; |
1431 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); | 1487 ElementsKind elements_kind = FLAG_smi_only_arrays |
1432 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1488 ? FAST_SMI_ONLY_ELEMENTS |
1433 } | 1489 : FAST_ELEMENTS; |
1490 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind); | |
1491 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
1434 set_map(Map::cast(obj)); | 1492 set_map(Map::cast(obj)); |
1435 initialize_elements(); | 1493 initialize_elements(); |
1436 return this; | 1494 return this; |
1437 } | 1495 } |
1438 | 1496 |
1439 | 1497 |
1440 ACCESSORS(Oddball, to_string, String, kToStringOffset) | 1498 ACCESSORS(Oddball, to_string, String, kToStringOffset) |
1441 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) | 1499 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) |
1442 | 1500 |
1443 | 1501 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1761 int offset = kHeaderSize + old_length * kDoubleSize; | 1819 int offset = kHeaderSize + old_length * kDoubleSize; |
1762 for (int current = from->length(); current < length(); ++current) { | 1820 for (int current = from->length(); current < length(); ++current) { |
1763 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); | 1821 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
1764 offset += kDoubleSize; | 1822 offset += kDoubleSize; |
1765 } | 1823 } |
1766 } | 1824 } |
1767 | 1825 |
1768 | 1826 |
1769 void FixedDoubleArray::Initialize(FixedArray* from) { | 1827 void FixedDoubleArray::Initialize(FixedArray* from) { |
1770 int old_length = from->length(); | 1828 int old_length = from->length(); |
1771 ASSERT(old_length < length()); | 1829 ASSERT(old_length <= length()); |
1772 for (int i = 0; i < old_length; i++) { | 1830 for (int i = 0; i < old_length; i++) { |
1773 Object* hole_or_object = from->get(i); | 1831 Object* hole_or_object = from->get(i); |
1774 if (hole_or_object->IsTheHole()) { | 1832 if (hole_or_object->IsTheHole()) { |
1775 set_the_hole(i); | 1833 set_the_hole(i); |
1776 } else { | 1834 } else { |
1777 set(i, hole_or_object->Number()); | 1835 set(i, hole_or_object->Number()); |
1778 } | 1836 } |
1779 } | 1837 } |
1780 int offset = kHeaderSize + old_length * kDoubleSize; | 1838 int offset = kHeaderSize + old_length * kDoubleSize; |
1781 for (int current = from->length(); current < length(); ++current) { | 1839 for (int current = from->length(); current < length(); ++current) { |
(...skipping 2276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4058 if (value->IsSmi()) { | 4116 if (value->IsSmi()) { |
4059 fa->set_unchecked(index, Smi::cast(value)); | 4117 fa->set_unchecked(index, Smi::cast(value)); |
4060 } else { | 4118 } else { |
4061 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER); | 4119 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER); |
4062 } | 4120 } |
4063 } | 4121 } |
4064 | 4122 |
4065 | 4123 |
4066 ElementsKind JSObject::GetElementsKind() { | 4124 ElementsKind JSObject::GetElementsKind() { |
4067 ElementsKind kind = map()->elements_kind(); | 4125 ElementsKind kind = map()->elements_kind(); |
4068 ASSERT((kind == FAST_ELEMENTS && | 4126 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && |
4069 (elements()->map() == GetHeap()->fixed_array_map() || | 4127 (elements()->map() == GetHeap()->fixed_array_map() || |
4070 elements()->map() == GetHeap()->fixed_cow_array_map())) || | 4128 elements()->map() == GetHeap()->fixed_cow_array_map())) || |
4071 (kind == FAST_DOUBLE_ELEMENTS && | 4129 (kind == FAST_DOUBLE_ELEMENTS && |
4072 elements()->IsFixedDoubleArray()) || | 4130 elements()->IsFixedDoubleArray()) || |
4073 (kind == DICTIONARY_ELEMENTS && | 4131 (kind == DICTIONARY_ELEMENTS && |
4074 elements()->IsFixedArray() && | 4132 elements()->IsFixedArray() && |
4075 elements()->IsDictionary()) || | 4133 elements()->IsDictionary()) || |
4076 (kind > DICTIONARY_ELEMENTS)); | 4134 (kind > DICTIONARY_ELEMENTS)); |
4077 return kind; | 4135 return kind; |
4078 } | 4136 } |
4079 | 4137 |
4080 | 4138 |
4081 ElementsAccessor* JSObject::GetElementsAccessor() { | 4139 ElementsAccessor* JSObject::GetElementsAccessor() { |
4082 return ElementsAccessor::ForKind(GetElementsKind()); | 4140 return ElementsAccessor::ForKind(GetElementsKind()); |
4083 } | 4141 } |
4084 | 4142 |
4085 | 4143 |
4086 bool JSObject::HasFastElements() { | 4144 bool JSObject::HasFastElements() { |
4087 return GetElementsKind() == FAST_ELEMENTS; | 4145 return GetElementsKind() == FAST_ELEMENTS; |
4088 } | 4146 } |
4089 | 4147 |
4090 | 4148 |
4149 bool JSObject::HasFastSmiOnlyElements() { | |
4150 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; | |
4151 } | |
4152 | |
4153 | |
4091 bool JSObject::HasFastDoubleElements() { | 4154 bool JSObject::HasFastDoubleElements() { |
4092 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; | 4155 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; |
4093 } | 4156 } |
4094 | 4157 |
4095 | 4158 |
4096 bool JSObject::HasDictionaryElements() { | 4159 bool JSObject::HasDictionaryElements() { |
4097 return GetElementsKind() == DICTIONARY_ELEMENTS; | 4160 return GetElementsKind() == DICTIONARY_ELEMENTS; |
4098 } | 4161 } |
4099 | 4162 |
4100 | 4163 |
4164 bool JSObject::HasNonStrictArgumentsElements() { | |
4165 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; | |
4166 } | |
4167 | |
4168 | |
4101 bool JSObject::HasExternalArrayElements() { | 4169 bool JSObject::HasExternalArrayElements() { |
4102 HeapObject* array = elements(); | 4170 HeapObject* array = elements(); |
4103 ASSERT(array != NULL); | 4171 ASSERT(array != NULL); |
4104 return array->IsExternalArray(); | 4172 return array->IsExternalArray(); |
4105 } | 4173 } |
4106 | 4174 |
4107 | 4175 |
4108 #define EXTERNAL_ELEMENTS_CHECK(name, type) \ | 4176 #define EXTERNAL_ELEMENTS_CHECK(name, type) \ |
4109 bool JSObject::HasExternal##name##Elements() { \ | 4177 bool JSObject::HasExternal##name##Elements() { \ |
4110 HeapObject* array = elements(); \ | 4178 HeapObject* array = elements(); \ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4142 | 4210 |
4143 bool JSObject::AllowsSetElementsLength() { | 4211 bool JSObject::AllowsSetElementsLength() { |
4144 bool result = elements()->IsFixedArray() || | 4212 bool result = elements()->IsFixedArray() || |
4145 elements()->IsFixedDoubleArray(); | 4213 elements()->IsFixedDoubleArray(); |
4146 ASSERT(result == !HasExternalArrayElements()); | 4214 ASSERT(result == !HasExternalArrayElements()); |
4147 return result; | 4215 return result; |
4148 } | 4216 } |
4149 | 4217 |
4150 | 4218 |
4151 MaybeObject* JSObject::EnsureWritableFastElements() { | 4219 MaybeObject* JSObject::EnsureWritableFastElements() { |
4152 ASSERT(HasFastElements()); | 4220 ASSERT(HasFastElements() || HasFastSmiOnlyElements()); |
4153 FixedArray* elems = FixedArray::cast(elements()); | 4221 FixedArray* elems = FixedArray::cast(elements()); |
4154 Isolate* isolate = GetIsolate(); | 4222 Isolate* isolate = GetIsolate(); |
4155 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 4223 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
4156 Object* writable_elems; | 4224 Object* writable_elems; |
4157 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( | 4225 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( |
4158 elems, isolate->heap()->fixed_array_map()); | 4226 elems, isolate->heap()->fixed_array_map()); |
4159 if (!maybe_writable_elems->ToObject(&writable_elems)) { | 4227 if (!maybe_writable_elems->ToObject(&writable_elems)) { |
4160 return maybe_writable_elems; | 4228 return maybe_writable_elems; |
4161 } | 4229 } |
4162 } | 4230 } |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4507 void Map::ClearCodeCache(Heap* heap) { | 4575 void Map::ClearCodeCache(Heap* heap) { |
4508 // No write barrier is needed since empty_fixed_array is not in new space. | 4576 // No write barrier is needed since empty_fixed_array is not in new space. |
4509 // Please note this function is used during marking: | 4577 // Please note this function is used during marking: |
4510 // - MarkCompactCollector::MarkUnmarkedObject | 4578 // - MarkCompactCollector::MarkUnmarkedObject |
4511 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); | 4579 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); |
4512 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); | 4580 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); |
4513 } | 4581 } |
4514 | 4582 |
4515 | 4583 |
4516 void JSArray::EnsureSize(int required_size) { | 4584 void JSArray::EnsureSize(int required_size) { |
4517 ASSERT(HasFastElements()); | 4585 ASSERT(HasFastElements() || HasFastSmiOnlyElements()); |
4518 FixedArray* elts = FixedArray::cast(elements()); | 4586 FixedArray* elts = FixedArray::cast(elements()); |
4519 const int kArraySizeThatFitsComfortablyInNewSpace = 128; | 4587 const int kArraySizeThatFitsComfortablyInNewSpace = 128; |
4520 if (elts->length() < required_size) { | 4588 if (elts->length() < required_size) { |
4521 // Doubling in size would be overkill, but leave some slack to avoid | 4589 // Doubling in size would be overkill, but leave some slack to avoid |
4522 // constantly growing. | 4590 // constantly growing. |
4523 Expand(required_size + (required_size >> 3)); | 4591 Expand(required_size + (required_size >> 3)); |
4524 // It's a performance benefit to keep a frequently used array in new-space. | 4592 // It's a performance benefit to keep a frequently used array in new-space. |
4525 } else if (!GetHeap()->new_space()->Contains(elts) && | 4593 } else if (!GetHeap()->new_space()->Contains(elts) && |
4526 required_size < kArraySizeThatFitsComfortablyInNewSpace) { | 4594 required_size < kArraySizeThatFitsComfortablyInNewSpace) { |
4527 // Expand will allocate a new backing store in new space even if the size | 4595 // Expand will allocate a new backing store in new space even if the size |
4528 // we asked for isn't larger than what we had before. | 4596 // we asked for isn't larger than what we had before. |
4529 Expand(required_size); | 4597 Expand(required_size); |
4530 } | 4598 } |
4531 } | 4599 } |
4532 | 4600 |
4533 | 4601 |
4534 void JSArray::set_length(Smi* length) { | 4602 void JSArray::set_length(Smi* length) { |
4535 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); | 4603 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); |
4536 } | 4604 } |
4537 | 4605 |
4538 | 4606 |
4539 void JSArray::SetContent(FixedArray* storage) { | 4607 MaybeObject* JSArray::SetContent(FixedArray* storage) { |
4608 MaybeObject* maybe_object = EnsureCanContainElements(storage); | |
4609 if (maybe_object->IsFailure()) return maybe_object; | |
4540 set_length(Smi::FromInt(storage->length())); | 4610 set_length(Smi::FromInt(storage->length())); |
4541 set_elements(storage); | 4611 set_elements(storage); |
4612 return this; | |
4542 } | 4613 } |
4543 | 4614 |
4544 | 4615 |
4545 MaybeObject* FixedArray::Copy() { | 4616 MaybeObject* FixedArray::Copy() { |
4546 if (length() == 0) return this; | 4617 if (length() == 0) return this; |
4547 return GetHeap()->CopyFixedArray(this); | 4618 return GetHeap()->CopyFixedArray(this); |
4548 } | 4619 } |
4549 | 4620 |
4550 | 4621 |
4551 Relocatable::Relocatable(Isolate* isolate) { | 4622 Relocatable::Relocatable(Isolate* isolate) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4648 #undef WRITE_INT_FIELD | 4719 #undef WRITE_INT_FIELD |
4649 #undef READ_SHORT_FIELD | 4720 #undef READ_SHORT_FIELD |
4650 #undef WRITE_SHORT_FIELD | 4721 #undef WRITE_SHORT_FIELD |
4651 #undef READ_BYTE_FIELD | 4722 #undef READ_BYTE_FIELD |
4652 #undef WRITE_BYTE_FIELD | 4723 #undef WRITE_BYTE_FIELD |
4653 | 4724 |
4654 | 4725 |
4655 } } // namespace v8::internal | 4726 } } // namespace v8::internal |
4656 | 4727 |
4657 #endif // V8_OBJECTS_INL_H_ | 4728 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |