| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 11912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11923 if (!it.IsConfigurable()) return false; | 11923 if (!it.IsConfigurable()) return false; |
| 11924 Handle<Object> value = | 11924 Handle<Object> value = |
| 11925 it.state() == LookupIterator::ACCESSOR | 11925 it.state() == LookupIterator::ACCESSOR |
| 11926 ? Handle<Object>::cast(isolate->factory()->the_hole_value()) | 11926 ? Handle<Object>::cast(isolate->factory()->the_hole_value()) |
| 11927 : JSReceiver::GetDataProperty(&it); | 11927 : JSReceiver::GetDataProperty(&it); |
| 11928 old_values->Add(value); | 11928 old_values->Add(value); |
| 11929 indices->Add(index); | 11929 indices->Add(index); |
| 11930 return true; | 11930 return true; |
| 11931 } | 11931 } |
| 11932 | 11932 |
| 11933 MaybeHandle<Object> JSArray::SetElementsLength( | |
| 11934 Handle<JSArray> array, | |
| 11935 Handle<Object> new_length_handle) { | |
| 11936 if (array->HasFastElements() && | |
| 11937 SetElementsLengthWouldNormalize(array->GetHeap(), new_length_handle)) { | |
| 11938 NormalizeElements(array); | |
| 11939 } | |
| 11940 | 11933 |
| 11934 void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) { |
| 11941 // We should never end in here with a pixel or external array. | 11935 // We should never end in here with a pixel or external array. |
| 11942 DCHECK(array->AllowsSetElementsLength()); | 11936 DCHECK(array->AllowsSetLength()); |
| 11937 array->GetElementsAccessor()->SetLength(array, new_length); |
| 11938 } |
| 11939 |
| 11940 |
| 11941 MaybeHandle<Object> JSArray::ObservableSetLength(Handle<JSArray> array, |
| 11942 uint32_t new_length) { |
| 11943 if (!array->map()->is_observed()) { | 11943 if (!array->map()->is_observed()) { |
| 11944 return array->GetElementsAccessor()->SetLength(array, new_length_handle); | 11944 SetLength(array, new_length); |
| 11945 return array; |
| 11945 } | 11946 } |
| 11946 | 11947 |
| 11947 Isolate* isolate = array->GetIsolate(); | 11948 Isolate* isolate = array->GetIsolate(); |
| 11948 List<uint32_t> indices; | 11949 List<uint32_t> indices; |
| 11949 List<Handle<Object> > old_values; | 11950 List<Handle<Object> > old_values; |
| 11950 Handle<Object> old_length_handle(array->length(), isolate); | 11951 Handle<Object> old_length_handle(array->length(), isolate); |
| 11951 uint32_t old_length = 0; | 11952 uint32_t old_length = 0; |
| 11952 CHECK(old_length_handle->ToArrayLength(&old_length)); | 11953 CHECK(old_length_handle->ToArrayLength(&old_length)); |
| 11953 uint32_t new_length = 0; | |
| 11954 CHECK(new_length_handle->ToArrayLength(&new_length)); | |
| 11955 | 11954 |
| 11956 static const PropertyAttributes kNoAttrFilter = NONE; | 11955 static const PropertyAttributes kNoAttrFilter = NONE; |
| 11957 int num_elements = array->NumberOfOwnElements(kNoAttrFilter); | 11956 int num_elements = array->NumberOfOwnElements(kNoAttrFilter); |
| 11958 if (num_elements > 0) { | 11957 if (num_elements > 0) { |
| 11959 if (old_length == static_cast<uint32_t>(num_elements)) { | 11958 if (old_length == static_cast<uint32_t>(num_elements)) { |
| 11960 // Simple case for arrays without holes. | 11959 // Simple case for arrays without holes. |
| 11961 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11960 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
| 11962 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; | 11961 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; |
| 11963 } | 11962 } |
| 11964 } else { | 11963 } else { |
| 11965 // For sparse arrays, only iterate over existing elements. | 11964 // For sparse arrays, only iterate over existing elements. |
| 11966 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over | 11965 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
| 11967 // the to-be-removed indices twice. | 11966 // the to-be-removed indices twice. |
| 11968 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11967 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
| 11969 array->GetOwnElementKeys(*keys, kNoAttrFilter); | 11968 array->GetOwnElementKeys(*keys, kNoAttrFilter); |
| 11970 while (num_elements-- > 0) { | 11969 while (num_elements-- > 0) { |
| 11971 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11970 uint32_t index = NumberToUint32(keys->get(num_elements)); |
| 11972 if (index < new_length) break; | 11971 if (index < new_length) break; |
| 11973 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; | 11972 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; |
| 11974 } | 11973 } |
| 11975 } | 11974 } |
| 11976 } | 11975 } |
| 11977 | 11976 |
| 11978 Handle<Object> hresult; | 11977 SetLength(array, new_length); |
| 11979 ASSIGN_RETURN_ON_EXCEPTION( | |
| 11980 isolate, hresult, | |
| 11981 array->GetElementsAccessor()->SetLength(array, new_length_handle), | |
| 11982 Object); | |
| 11983 | 11978 |
| 11984 CHECK(array->length()->ToArrayLength(&new_length)); | 11979 CHECK(array->length()->ToArrayLength(&new_length)); |
| 11985 if (old_length == new_length) return hresult; | 11980 if (old_length == new_length) return array; |
| 11986 | 11981 |
| 11987 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); | 11982 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); |
| 11988 | 11983 |
| 11989 for (int i = 0; i < indices.length(); ++i) { | 11984 for (int i = 0; i < indices.length(); ++i) { |
| 11990 // For deletions where the property was an accessor, old_values[i] | 11985 // For deletions where the property was an accessor, old_values[i] |
| 11991 // will be the hole, which instructs EnqueueChangeRecord to elide | 11986 // will be the hole, which instructs EnqueueChangeRecord to elide |
| 11992 // the "oldValue" property. | 11987 // the "oldValue" property. |
| 11993 RETURN_ON_EXCEPTION( | 11988 RETURN_ON_EXCEPTION( |
| 11994 isolate, | 11989 isolate, |
| 11995 JSObject::EnqueueChangeRecord( | 11990 JSObject::EnqueueChangeRecord( |
| 11996 array, "delete", isolate->factory()->Uint32ToString(indices[i]), | 11991 array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
| 11997 old_values[i]), | 11992 old_values[i]), |
| 11998 Object); | 11993 Object); |
| 11999 } | 11994 } |
| 11995 |
| 12000 RETURN_ON_EXCEPTION(isolate, | 11996 RETURN_ON_EXCEPTION(isolate, |
| 12001 JSObject::EnqueueChangeRecord( | 11997 JSObject::EnqueueChangeRecord( |
| 12002 array, "update", isolate->factory()->length_string(), | 11998 array, "update", isolate->factory()->length_string(), |
| 12003 old_length_handle), | 11999 old_length_handle), |
| 12004 Object); | 12000 Object); |
| 12005 | 12001 |
| 12006 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); | 12002 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); |
| 12007 | 12003 |
| 12008 uint32_t index = Min(old_length, new_length); | 12004 uint32_t index = Min(old_length, new_length); |
| 12009 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 12005 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
| 12010 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 12006 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
| 12011 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12007 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12012 if (delete_count > 0) { | 12008 if (delete_count > 0) { |
| 12013 for (int i = indices.length() - 1; i >= 0; i--) { | 12009 for (int i = indices.length() - 1; i >= 0; i--) { |
| 12014 // Skip deletions where the property was an accessor, leaving holes | 12010 // Skip deletions where the property was an accessor, leaving holes |
| 12015 // in the array of old values. | 12011 // in the array of old values. |
| 12016 if (old_values[i]->IsTheHole()) continue; | 12012 if (old_values[i]->IsTheHole()) continue; |
| 12017 JSObject::AddDataElement(deleted, indices[i] - index, old_values[i], NONE) | 12013 JSObject::AddDataElement(deleted, indices[i] - index, old_values[i], NONE) |
| 12018 .Assert(); | 12014 .Assert(); |
| 12019 } | 12015 } |
| 12020 | 12016 |
| 12021 ElementsAccessor* accessor = deleted->GetElementsAccessor(); | 12017 JSArray::SetLength(deleted, delete_count); |
| 12022 accessor->SetLength(deleted, isolate->factory()->NewNumberFromUint( | |
| 12023 delete_count)).Check(); | |
| 12024 } | 12018 } |
| 12025 | 12019 |
| 12026 RETURN_ON_EXCEPTION( | 12020 RETURN_ON_EXCEPTION( |
| 12027 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); | 12021 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); |
| 12028 | 12022 |
| 12029 return hresult; | 12023 return array; |
| 12030 } | 12024 } |
| 12031 | 12025 |
| 12032 | 12026 |
| 12033 // static | 12027 // static |
| 12034 void Map::AddDependentCode(Handle<Map> map, | 12028 void Map::AddDependentCode(Handle<Map> map, |
| 12035 DependentCode::DependencyGroup group, | 12029 DependentCode::DependencyGroup group, |
| 12036 Handle<Code> code) { | 12030 Handle<Code> code) { |
| 12037 Handle<WeakCell> cell = Code::WeakCellFor(code); | 12031 Handle<WeakCell> cell = Code::WeakCellFor(code); |
| 12038 Handle<DependentCode> codes = DependentCode::InsertWeakCode( | 12032 Handle<DependentCode> codes = DependentCode::InsertWeakCode( |
| 12039 Handle<DependentCode>(map->dependent_code()), group, cell); | 12033 Handle<DependentCode>(map->dependent_code()), group, cell); |
| (...skipping 4620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16660 Handle<Object> new_value) { | 16654 Handle<Object> new_value) { |
| 16661 if (cell->value() != *new_value) { | 16655 if (cell->value() != *new_value) { |
| 16662 cell->set_value(*new_value); | 16656 cell->set_value(*new_value); |
| 16663 Isolate* isolate = cell->GetIsolate(); | 16657 Isolate* isolate = cell->GetIsolate(); |
| 16664 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16658 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16665 isolate, DependentCode::kPropertyCellChangedGroup); | 16659 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16666 } | 16660 } |
| 16667 } | 16661 } |
| 16668 } // namespace internal | 16662 } // namespace internal |
| 16669 } // namespace v8 | 16663 } // namespace v8 |
| OLD | NEW |