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()); |
11943 if (!array->map()->is_observed()) { | 11937 array->GetElementsAccessor()->SetLength(array, new_length); |
11944 return array->GetElementsAccessor()->SetLength(array, new_length_handle); | 11938 } |
11945 } | |
11946 | 11939 |
11940 | |
11941 MaybeHandle<Object> JSArray::ObserveableSetLength(Handle<JSArray> array, | |
Jakob Kummerow
2015/06/19 13:23:12
nit: "observable" (one less 'e') is the far more c
| |
11942 uint32_t new_length) { | |
11947 Isolate* isolate = array->GetIsolate(); | 11943 Isolate* isolate = array->GetIsolate(); |
11948 List<uint32_t> indices; | 11944 List<uint32_t> indices; |
11949 List<Handle<Object> > old_values; | 11945 List<Handle<Object> > old_values; |
11950 Handle<Object> old_length_handle(array->length(), isolate); | 11946 Handle<Object> old_length_handle(array->length(), isolate); |
11951 uint32_t old_length = 0; | 11947 uint32_t old_length = 0; |
11952 CHECK(old_length_handle->ToArrayLength(&old_length)); | 11948 CHECK(old_length_handle->ToArrayLength(&old_length)); |
11953 uint32_t new_length = 0; | |
11954 CHECK(new_length_handle->ToArrayLength(&new_length)); | |
11955 | 11949 |
11956 static const PropertyAttributes kNoAttrFilter = NONE; | 11950 static const PropertyAttributes kNoAttrFilter = NONE; |
11957 int num_elements = array->NumberOfOwnElements(kNoAttrFilter); | 11951 int num_elements = array->NumberOfOwnElements(kNoAttrFilter); |
11958 if (num_elements > 0) { | 11952 if (num_elements > 0) { |
11959 if (old_length == static_cast<uint32_t>(num_elements)) { | 11953 if (old_length == static_cast<uint32_t>(num_elements)) { |
11960 // Simple case for arrays without holes. | 11954 // Simple case for arrays without holes. |
11961 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11955 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
11962 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; | 11956 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; |
11963 } | 11957 } |
11964 } else { | 11958 } else { |
11965 // For sparse arrays, only iterate over existing elements. | 11959 // For sparse arrays, only iterate over existing elements. |
11966 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over | 11960 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
11967 // the to-be-removed indices twice. | 11961 // the to-be-removed indices twice. |
11968 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11962 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
11969 array->GetOwnElementKeys(*keys, kNoAttrFilter); | 11963 array->GetOwnElementKeys(*keys, kNoAttrFilter); |
11970 while (num_elements-- > 0) { | 11964 while (num_elements-- > 0) { |
11971 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11965 uint32_t index = NumberToUint32(keys->get(num_elements)); |
11972 if (index < new_length) break; | 11966 if (index < new_length) break; |
11973 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; | 11967 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; |
11974 } | 11968 } |
11975 } | 11969 } |
11976 } | 11970 } |
11977 | 11971 |
11978 Handle<Object> hresult; | 11972 SetLength(array, new_length); |
11979 ASSIGN_RETURN_ON_EXCEPTION( | |
11980 isolate, hresult, | |
11981 array->GetElementsAccessor()->SetLength(array, new_length_handle), | |
11982 Object); | |
11983 | 11973 |
11984 CHECK(array->length()->ToArrayLength(&new_length)); | 11974 CHECK(array->length()->ToArrayLength(&new_length)); |
11985 if (old_length == new_length) return hresult; | 11975 if (old_length == new_length) return array; |
11986 | 11976 |
11987 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); | 11977 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); |
11988 | 11978 |
11989 for (int i = 0; i < indices.length(); ++i) { | 11979 for (int i = 0; i < indices.length(); ++i) { |
11990 // For deletions where the property was an accessor, old_values[i] | 11980 // For deletions where the property was an accessor, old_values[i] |
11991 // will be the hole, which instructs EnqueueChangeRecord to elide | 11981 // will be the hole, which instructs EnqueueChangeRecord to elide |
11992 // the "oldValue" property. | 11982 // the "oldValue" property. |
11993 RETURN_ON_EXCEPTION( | 11983 RETURN_ON_EXCEPTION( |
11994 isolate, | 11984 isolate, |
11995 JSObject::EnqueueChangeRecord( | 11985 JSObject::EnqueueChangeRecord( |
11996 array, "delete", isolate->factory()->Uint32ToString(indices[i]), | 11986 array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
11997 old_values[i]), | 11987 old_values[i]), |
11998 Object); | 11988 Object); |
11999 } | 11989 } |
11990 | |
12000 RETURN_ON_EXCEPTION(isolate, | 11991 RETURN_ON_EXCEPTION(isolate, |
12001 JSObject::EnqueueChangeRecord( | 11992 JSObject::EnqueueChangeRecord( |
12002 array, "update", isolate->factory()->length_string(), | 11993 array, "update", isolate->factory()->length_string(), |
12003 old_length_handle), | 11994 old_length_handle), |
12004 Object); | 11995 Object); |
12005 | 11996 |
12006 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); | 11997 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); |
12007 | 11998 |
12008 uint32_t index = Min(old_length, new_length); | 11999 uint32_t index = Min(old_length, new_length); |
12009 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 12000 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; | 12001 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
12011 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12002 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
12012 if (delete_count > 0) { | 12003 if (delete_count > 0) { |
12013 for (int i = indices.length() - 1; i >= 0; i--) { | 12004 for (int i = indices.length() - 1; i >= 0; i--) { |
12014 // Skip deletions where the property was an accessor, leaving holes | 12005 // Skip deletions where the property was an accessor, leaving holes |
12015 // in the array of old values. | 12006 // in the array of old values. |
12016 if (old_values[i]->IsTheHole()) continue; | 12007 if (old_values[i]->IsTheHole()) continue; |
12017 JSObject::AddDataElement(deleted, indices[i] - index, old_values[i], NONE) | 12008 JSObject::AddDataElement(deleted, indices[i] - index, old_values[i], NONE) |
12018 .Assert(); | 12009 .Assert(); |
12019 } | 12010 } |
12020 | 12011 |
12021 ElementsAccessor* accessor = deleted->GetElementsAccessor(); | 12012 JSArray::SetLength(deleted, delete_count); |
12022 accessor->SetLength(deleted, isolate->factory()->NewNumberFromUint( | |
12023 delete_count)).Check(); | |
12024 } | 12013 } |
12025 | 12014 |
12026 RETURN_ON_EXCEPTION( | 12015 RETURN_ON_EXCEPTION( |
12027 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); | 12016 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); |
12028 | 12017 |
12029 return hresult; | 12018 return array; |
12030 } | 12019 } |
12031 | 12020 |
12032 | 12021 |
12033 // static | 12022 // static |
12034 void Map::AddDependentCode(Handle<Map> map, | 12023 void Map::AddDependentCode(Handle<Map> map, |
12035 DependentCode::DependencyGroup group, | 12024 DependentCode::DependencyGroup group, |
12036 Handle<Code> code) { | 12025 Handle<Code> code) { |
12037 Handle<WeakCell> cell = Code::WeakCellFor(code); | 12026 Handle<WeakCell> cell = Code::WeakCellFor(code); |
12038 Handle<DependentCode> codes = DependentCode::InsertWeakCode( | 12027 Handle<DependentCode> codes = DependentCode::InsertWeakCode( |
12039 Handle<DependentCode>(map->dependent_code()), group, cell); | 12028 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) { | 16649 Handle<Object> new_value) { |
16661 if (cell->value() != *new_value) { | 16650 if (cell->value() != *new_value) { |
16662 cell->set_value(*new_value); | 16651 cell->set_value(*new_value); |
16663 Isolate* isolate = cell->GetIsolate(); | 16652 Isolate* isolate = cell->GetIsolate(); |
16664 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16653 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16665 isolate, DependentCode::kPropertyCellChangedGroup); | 16654 isolate, DependentCode::kPropertyCellChangedGroup); |
16666 } | 16655 } |
16667 } | 16656 } |
16668 } // namespace internal | 16657 } // namespace internal |
16669 } // namespace v8 | 16658 } // namespace v8 |
OLD | NEW |