| Index: src/objects-inl.h
|
| diff --git a/src/objects-inl.h b/src/objects-inl.h
|
| index 72dca225900ae5815fb92b106d86351aaa01b069..f03021e41c07c1cfb3b926b4b2b5d841f7bd5382 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,88 @@ void FixedArray::set(int index, Object* value) {
|
| }
|
|
|
|
|
| +double FixedDoubleArray::get(int index) {
|
| + ASSERT(map() != HEAP->fixed_cow_array_map() &&
|
| + map() != HEAP->fixed_array_map());
|
| + 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() &&
|
| + map() != HEAP->fixed_array_map());
|
| + 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() &&
|
| + map() != HEAP->fixed_array_map());
|
| + 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 +1997,7 @@ void NumberDictionary::set_requires_slow_elements() {
|
|
|
|
|
| CAST_ACCESSOR(FixedArray)
|
| +CAST_ACCESSOR(FixedDoubleArray)
|
| CAST_ACCESSOR(DescriptorArray)
|
| CAST_ACCESSOR(DeoptimizationInputData)
|
| CAST_ACCESSOR(DeoptimizationOutputData)
|
| @@ -1964,7 +2062,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 +2521,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 +3083,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 +3903,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 +3918,11 @@ bool JSObject::HasFastElements() {
|
| }
|
|
|
|
|
| +bool JSObject::HasFastDoubleElements() {
|
| + return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
|
| +}
|
| +
|
| +
|
| bool JSObject::HasDictionaryElements() {
|
| return GetElementsKind() == DICTIONARY_ELEMENTS;
|
| }
|
|
|