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 |