Chromium Code Reviews| Index: src/objects-inl.h |
| diff --git a/src/objects-inl.h b/src/objects-inl.h |
| index 72dca225900ae5815fb92b106d86351aaa01b069..80cf80f43164d4eed296823af42523578345f33a 100644 |
| --- a/src/objects-inl.h |
| +++ b/src/objects-inl.h |
| @@ -217,6 +217,10 @@ bool Object::IsExternalTwoByteString() { |
| String::cast(this)->IsTwoByteRepresentation(); |
| } |
| +bool Object::HasValidElements() { |
| + // Dictionary is covered under FixedArray. |
| + return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray(); |
| +} |
| StringShape::StringShape(String* str) |
| : type_(str->map()->instance_type()) { |
| @@ -489,6 +493,13 @@ bool Object::IsFixedArray() { |
| } |
| +bool Object::IsFixedDoubleArray() { |
| + return Object::IsHeapObject() |
| + && HeapObject::cast(this)->map()->instance_type() == |
| + FIXED_DOUBLE_ARRAY_TYPE; |
| +} |
| + |
| + |
| bool Object::IsDescriptorArray() { |
| return IsFixedArray(); |
| } |
| @@ -1318,8 +1329,7 @@ ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
| HeapObject* JSObject::elements() { |
| Object* array = READ_FIELD(this, kElementsOffset); |
| - // In the assert below Dictionary is covered under FixedArray. |
| - ASSERT(array->IsFixedArray() || array->IsExternalArray()); |
| + ASSERT(array->HasValidElements()); |
| return reinterpret_cast<HeapObject*>(array); |
| } |
| @@ -1328,8 +1338,7 @@ void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { |
| ASSERT(map()->has_fast_elements() == |
| (value->map() == GetHeap()->fixed_array_map() || |
| value->map() == GetHeap()->fixed_cow_array_map())); |
| - // In the assert below Dictionary is covered under FixedArray. |
| - ASSERT(value->IsFixedArray() || value->IsExternalArray()); |
| + ASSERT(value->HasValidElements()); |
| WRITE_FIELD(this, kElementsOffset, value); |
| CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode); |
| } |
| @@ -1577,6 +1586,12 @@ bool Object::IsStringObjectWithCharacterAt(uint32_t index) { |
| } |
| +FixedArrayBase* FixedArrayBase::cast(Object* object) { |
| + ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray()); |
| + return reinterpret_cast<FixedArrayBase*>(object); |
| +} |
| + |
| + |
| Object* FixedArray::get(int index) { |
| ASSERT(index >= 0 && index < this->length()); |
| return READ_FIELD(this, kHeaderSize + index * kPointerSize); |
| @@ -1600,6 +1615,84 @@ void FixedArray::set(int index, Object* value) { |
| } |
| +double FixedDoubleArray::get(int index) { |
| + ASSERT(index >= 0 && index < this->length()); |
| + double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize); |
| + ASSERT(!is_the_hole_nan(result)); |
| + return result; |
| +} |
| + |
| + |
| +void FixedDoubleArray::set(int index, double value) { |
| + ASSERT(map() != HEAP->fixed_cow_array_map()); |
|
Mads Ager (chromium)
2011/06/08 13:13:13
If you assert for fixed_cow_array_map should you a
danno
2011/06/09 09:45:40
Done.
|
| + int offset = kHeaderSize + index * kDoubleSize; |
| + if (isnan(value)) value = canonical_not_the_hole_nan_as_double(); |
| + WRITE_DOUBLE_FIELD(this, offset, value); |
| +} |
| + |
| + |
| +void FixedDoubleArray::set_the_hole(int index) { |
| + ASSERT(map() != HEAP->fixed_cow_array_map()); |
|
Mads Ager (chromium)
2011/06/08 13:13:13
Ditto?
danno
2011/06/09 09:45:40
Done.
|
| + int offset = kHeaderSize + index * kDoubleSize; |
| + WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
| +} |
| + |
| + |
| +bool FixedDoubleArray::is_the_hole(int index) { |
| + int offset = kHeaderSize + index * kDoubleSize; |
| + return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset)); |
| +} |
| + |
| + |
| +void FixedDoubleArray::Initialize(FixedDoubleArray* from) { |
| + int old_length = from->length(); |
| + ASSERT(old_length < length()); |
| + OS::MemCopy(FIELD_ADDR(this, kHeaderSize), |
| + FIELD_ADDR(from, kHeaderSize), |
| + old_length * kDoubleSize); |
| + int offset = kHeaderSize + old_length * kDoubleSize; |
| + for (int current = from->length(); current < length(); ++current) { |
| + WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
| + offset += kDoubleSize; |
| + } |
| +} |
| + |
| + |
| +void FixedDoubleArray::Initialize(FixedArray* from) { |
| + int old_length = from->length(); |
| + ASSERT(old_length < length()); |
| + for (int i = 0; i < old_length; i++) { |
| + Object* hole_or_object = from->get(i); |
| + if (hole_or_object->IsTheHole()) { |
| + set_the_hole(i); |
| + } else { |
| + set(i, hole_or_object->Number()); |
| + } |
| + } |
| + int offset = kHeaderSize + old_length * kDoubleSize; |
| + for (int current = from->length(); current < length(); ++current) { |
| + WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
| + offset += kDoubleSize; |
| + } |
| +} |
| + |
| + |
| +void FixedDoubleArray::Initialize(NumberDictionary* from) { |
| + int offset = kHeaderSize; |
| + for (int current = 0; current < length(); ++current) { |
| + WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
| + offset += kDoubleSize; |
| + } |
| + for (int i = 0; i < from->Capacity(); i++) { |
| + Object* key = from->KeyAt(i); |
| + if (key->IsNumber()) { |
| + uint32_t entry = static_cast<uint32_t>(key->Number()); |
| + set(entry, from->ValueAt(i)->Number()); |
| + } |
| + } |
| +} |
| + |
| + |
| WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { |
| if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER; |
| return UPDATE_WRITE_BARRIER; |
| @@ -1900,6 +1993,7 @@ void NumberDictionary::set_requires_slow_elements() { |
| CAST_ACCESSOR(FixedArray) |
| +CAST_ACCESSOR(FixedDoubleArray) |
| CAST_ACCESSOR(DescriptorArray) |
| CAST_ACCESSOR(DeoptimizationInputData) |
| CAST_ACCESSOR(DeoptimizationOutputData) |
| @@ -1964,7 +2058,7 @@ HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { |
| } |
| -SMI_ACCESSORS(FixedArray, length, kLengthOffset) |
| +SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) |
| SMI_ACCESSORS(ByteArray, length, kLengthOffset) |
| INT_ACCESSORS(ExternalArray, length, kLengthOffset) |
| @@ -2423,6 +2517,10 @@ int HeapObject::SizeFromMap(Map* map) { |
| return SeqTwoByteString::SizeFor( |
| reinterpret_cast<SeqTwoByteString*>(this)->length()); |
| } |
| + if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |
| + return FixedDoubleArray::SizeFor( |
| + reinterpret_cast<FixedDoubleArray*>(this)->length()); |
| + } |
| ASSERT(instance_type == CODE_TYPE); |
| return reinterpret_cast<Code*>(this)->CodeSize(); |
| } |
| @@ -2981,20 +3079,33 @@ MaybeObject* Map::GetFastElementsMap() { |
| } |
| Map* new_map = Map::cast(obj); |
| new_map->set_elements_kind(JSObject::FAST_ELEMENTS); |
| - isolate()->counters()->map_slow_to_fast_elements()->Increment(); |
| + isolate()->counters()->map_to_fast_elements()->Increment(); |
| + return new_map; |
| +} |
| + |
| + |
| +MaybeObject* Map::GetFastDoubleElementsMap() { |
| + if (has_fast_double_elements()) return this; |
| + Object* obj; |
| + { MaybeObject* maybe_obj = CopyDropTransitions(); |
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| + } |
| + Map* new_map = Map::cast(obj); |
| + new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS); |
| + isolate()->counters()->map_to_fast_double_elements()->Increment(); |
| return new_map; |
| } |
| MaybeObject* Map::GetSlowElementsMap() { |
| - if (!has_fast_elements()) return this; |
| + if (!has_fast_elements() && !has_fast_double_elements()) return this; |
| Object* obj; |
| { MaybeObject* maybe_obj = CopyDropTransitions(); |
| if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| } |
| Map* new_map = Map::cast(obj); |
| new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS); |
| - isolate()->counters()->map_fast_to_slow_elements()->Increment(); |
| + isolate()->counters()->map_to_slow_elements()->Increment(); |
| return new_map; |
| } |
| @@ -3788,6 +3899,8 @@ JSObject::ElementsKind JSObject::GetElementsKind() { |
| ASSERT((kind == FAST_ELEMENTS && |
| (elements()->map() == GetHeap()->fixed_array_map() || |
| elements()->map() == GetHeap()->fixed_cow_array_map())) || |
| + (kind == FAST_DOUBLE_ELEMENTS && |
| + elements()->IsFixedDoubleArray()) || |
| (kind == DICTIONARY_ELEMENTS && |
| elements()->IsFixedArray() && |
| elements()->IsDictionary()) || |
| @@ -3801,6 +3914,11 @@ bool JSObject::HasFastElements() { |
| } |
| +bool JSObject::HasFastDoubleElements() { |
| + return GetElementsKind() == FAST_DOUBLE_ELEMENTS; |
| +} |
| + |
| + |
| bool JSObject::HasDictionaryElements() { |
| return GetElementsKind() == DICTIONARY_ELEMENTS; |
| } |