| Index: src/objects-inl.h
|
| diff --git a/src/objects-inl.h b/src/objects-inl.h
|
| index e7559e4f54b0b0d996ebb3591fb5bed3efdef03a..f37fdab320498a8d871547e9e9fa183685019546 100644
|
| --- a/src/objects-inl.h
|
| +++ b/src/objects-inl.h
|
| @@ -1297,14 +1297,82 @@ FixedArrayBase* JSObject::elements() {
|
| return static_cast<FixedArrayBase*>(array);
|
| }
|
|
|
| +void JSObject::ValidateSmiOnlyElements() {
|
| +#if DEBUG
|
| + if (FLAG_smi_only_arrays &&
|
| + map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
|
| + Heap* heap = GetHeap();
|
| + // Don't use elements, since integrity checks will fail if there
|
| + // are filler pointers in the array.
|
| + FixedArray* fixed_array =
|
| + reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
|
| + Map* map = fixed_array->map();
|
| + // Arrays that have been shifted in place can't be verified.
|
| + if (map != heap->raw_unchecked_one_pointer_filler_map() &&
|
| + map != heap->raw_unchecked_two_pointer_filler_map() &&
|
| + map != heap->free_space_map()) {
|
| + for (int i = 0; i < fixed_array->length(); i++) {
|
| + Object* current = fixed_array->get(i);
|
| + ASSERT(current->IsSmi() || current == heap->the_hole_value());
|
| + }
|
| + }
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +
|
| +MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
|
| +#if DEBUG
|
| + ValidateSmiOnlyElements();
|
| +#endif
|
| + if (FLAG_smi_only_arrays &&
|
| + (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
|
| + Object* obj;
|
| + MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + set_map(Map::cast(obj));
|
| + }
|
| + return this;
|
| +}
|
| +
|
| +
|
| +MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
|
| + uint32_t count) {
|
| + if (FLAG_smi_only_arrays &&
|
| + map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
|
| + for (uint32_t i = 0; i < count; ++i) {
|
| + Object* current = *objects++;
|
| + if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
|
| + return EnsureCanContainNonSmiElements();
|
| + }
|
| + }
|
| + }
|
| + return this;
|
| +}
|
| +
|
| +
|
| +MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
|
| + if (FLAG_smi_only_arrays) {
|
| + Object** objects = reinterpret_cast<Object**>(
|
| + FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
|
| + return EnsureCanContainElements(objects, elements->length());
|
| + } else {
|
| + return this;
|
| + }
|
| +}
|
| +
|
|
|
| void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
|
| - ASSERT(map()->has_fast_elements() ==
|
| + ASSERT((map()->has_fast_elements() ||
|
| + map()->has_fast_smi_only_elements()) ==
|
| (value->map() == GetHeap()->fixed_array_map() ||
|
| value->map() == GetHeap()->fixed_cow_array_map()));
|
| ASSERT(map()->has_fast_double_elements() ==
|
| value->IsFixedDoubleArray());
|
| ASSERT(value->HasValidElements());
|
| +#ifdef DEBUG
|
| + ValidateSmiOnlyElements();
|
| +#endif
|
| WRITE_FIELD(this, kElementsOffset, value);
|
| CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
|
| }
|
| @@ -1317,7 +1385,7 @@ void JSObject::initialize_properties() {
|
|
|
|
|
| void JSObject::initialize_elements() {
|
| - ASSERT(map()->has_fast_elements());
|
| + ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
|
| ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
|
| WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
|
| }
|
| @@ -1325,9 +1393,11 @@ void JSObject::initialize_elements() {
|
|
|
| MaybeObject* JSObject::ResetElements() {
|
| Object* obj;
|
| - { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
|
| - if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| - }
|
| + ElementsKind elements_kind = FLAG_smi_only_arrays
|
| + ? FAST_SMI_ONLY_ELEMENTS
|
| + : FAST_ELEMENTS;
|
| + MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| set_map(Map::cast(obj));
|
| initialize_elements();
|
| return this;
|
| @@ -1683,7 +1753,7 @@ void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
|
|
|
| void FixedDoubleArray::Initialize(FixedArray* from) {
|
| int old_length = from->length();
|
| - ASSERT(old_length < 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()) {
|
| @@ -3952,15 +4022,20 @@ void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
|
|
|
| ElementsKind JSObject::GetElementsKind() {
|
| ElementsKind kind = map()->elements_kind();
|
| - ASSERT((kind == FAST_ELEMENTS &&
|
| - (elements()->map() == GetHeap()->fixed_array_map() ||
|
| - elements()->map() == GetHeap()->fixed_cow_array_map())) ||
|
| +#if DEBUG
|
| + FixedArrayBase* fixed_array =
|
| + reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
|
| + Map* map = fixed_array->map();
|
| + ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
|
| + (map == GetHeap()->fixed_array_map() ||
|
| + map == GetHeap()->fixed_cow_array_map())) ||
|
| (kind == FAST_DOUBLE_ELEMENTS &&
|
| - elements()->IsFixedDoubleArray()) ||
|
| + fixed_array->IsFixedDoubleArray()) ||
|
| (kind == DICTIONARY_ELEMENTS &&
|
| - elements()->IsFixedArray() &&
|
| - elements()->IsDictionary()) ||
|
| + fixed_array->IsFixedArray() &&
|
| + fixed_array->IsDictionary()) ||
|
| (kind > DICTIONARY_ELEMENTS));
|
| +#endif
|
| return kind;
|
| }
|
|
|
| @@ -3975,6 +4050,18 @@ bool JSObject::HasFastElements() {
|
| }
|
|
|
|
|
| +bool JSObject::HasFastSmiOnlyElements() {
|
| + return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
|
| +}
|
| +
|
| +
|
| +bool JSObject::HasFastTypeElements() {
|
| + ElementsKind elements_kind = GetElementsKind();
|
| + return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
|
| + elements_kind == FAST_ELEMENTS;
|
| +}
|
| +
|
| +
|
| bool JSObject::HasFastDoubleElements() {
|
| return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
|
| }
|
| @@ -3985,6 +4072,11 @@ bool JSObject::HasDictionaryElements() {
|
| }
|
|
|
|
|
| +bool JSObject::HasNonStrictArgumentsElements() {
|
| + return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
|
| +}
|
| +
|
| +
|
| bool JSObject::HasExternalArrayElements() {
|
| HeapObject* array = elements();
|
| ASSERT(array != NULL);
|
| @@ -4036,7 +4128,7 @@ bool JSObject::AllowsSetElementsLength() {
|
|
|
|
|
| MaybeObject* JSObject::EnsureWritableFastElements() {
|
| - ASSERT(HasFastElements());
|
| + ASSERT(HasFastTypeElements());
|
| FixedArray* elems = FixedArray::cast(elements());
|
| Isolate* isolate = GetIsolate();
|
| if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
|
| @@ -4401,7 +4493,7 @@ void Map::ClearCodeCache(Heap* heap) {
|
|
|
|
|
| void JSArray::EnsureSize(int required_size) {
|
| - ASSERT(HasFastElements());
|
| + ASSERT(HasFastTypeElements());
|
| FixedArray* elts = FixedArray::cast(elements());
|
| const int kArraySizeThatFitsComfortablyInNewSpace = 128;
|
| if (elts->length() < required_size) {
|
| @@ -4424,9 +4516,12 @@ void JSArray::set_length(Smi* length) {
|
| }
|
|
|
|
|
| -void JSArray::SetContent(FixedArray* storage) {
|
| +MaybeObject* JSArray::SetContent(FixedArray* storage) {
|
| + MaybeObject* maybe_object = EnsureCanContainElements(storage);
|
| + if (maybe_object->IsFailure()) return maybe_object;
|
| set_length(Smi::FromInt(storage->length()));
|
| set_elements(storage);
|
| + return this;
|
| }
|
|
|
|
|
|
|