| 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 6366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6377 desc->SetEnumCache(*bridge_storage, | 6377 desc->SetEnumCache(*bridge_storage, |
| 6378 *storage, | 6378 *storage, |
| 6379 indices.is_null() ? Object::cast(Smi::FromInt(0)) | 6379 indices.is_null() ? Object::cast(Smi::FromInt(0)) |
| 6380 : Object::cast(*indices)); | 6380 : Object::cast(*indices)); |
| 6381 if (cache_result) { | 6381 if (cache_result) { |
| 6382 object->map()->SetEnumLength(own_property_count); | 6382 object->map()->SetEnumLength(own_property_count); |
| 6383 } | 6383 } |
| 6384 return storage; | 6384 return storage; |
| 6385 } else if (object->IsGlobalObject()) { | 6385 } else if (object->IsGlobalObject()) { |
| 6386 Handle<GlobalDictionary> dictionary(object->global_dictionary()); | 6386 Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
| 6387 int length = dictionary->NumberOfEnumElements(*object); | 6387 int length = dictionary->NumberOfEnumElements(); |
| 6388 if (length == 0) { | 6388 if (length == 0) { |
| 6389 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); | 6389 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); |
| 6390 } | 6390 } |
| 6391 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); | 6391 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
| 6392 dictionary->CopyEnumKeysTo(*object, *storage); | 6392 dictionary->CopyEnumKeysTo(*storage); |
| 6393 return storage; | 6393 return storage; |
| 6394 } else { | 6394 } else { |
| 6395 Handle<NameDictionary> dictionary(object->property_dictionary()); | 6395 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 6396 int length = dictionary->NumberOfEnumElements(*object); | 6396 int length = dictionary->NumberOfEnumElements(); |
| 6397 if (length == 0) { | 6397 if (length == 0) { |
| 6398 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); | 6398 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); |
| 6399 } | 6399 } |
| 6400 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); | 6400 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
| 6401 dictionary->CopyEnumKeysTo(*object, *storage); | 6401 dictionary->CopyEnumKeysTo(*storage); |
| 6402 return storage; | 6402 return storage; |
| 6403 } | 6403 } |
| 6404 } | 6404 } |
| 6405 | 6405 |
| 6406 | 6406 |
| 6407 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 6407 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| 6408 KeyCollectionType type) { | 6408 KeyCollectionType type) { |
| 6409 USE(ContainsOnlyValidKeys); | 6409 USE(ContainsOnlyValidKeys); |
| 6410 Isolate* isolate = object->GetIsolate(); | 6410 Isolate* isolate = object->GetIsolate(); |
| 6411 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); | 6411 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); |
| (...skipping 7644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14056 int capacity = this->Capacity(); | 14056 int capacity = this->Capacity(); |
| 14057 for (int i = 0; i < capacity; i++) { | 14057 for (int i = 0; i < capacity; i++) { |
| 14058 Object* k = this->KeyAt(i); | 14058 Object* k = this->KeyAt(i); |
| 14059 if (this->IsKey(k)) { | 14059 if (this->IsKey(k)) { |
| 14060 os << " "; | 14060 os << " "; |
| 14061 if (k->IsString()) { | 14061 if (k->IsString()) { |
| 14062 String::cast(k)->StringPrint(os); | 14062 String::cast(k)->StringPrint(os); |
| 14063 } else { | 14063 } else { |
| 14064 os << Brief(k); | 14064 os << Brief(k); |
| 14065 } | 14065 } |
| 14066 os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n"; | 14066 os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i) |
| 14067 << "\n"; |
| 14067 } | 14068 } |
| 14068 } | 14069 } |
| 14069 } | 14070 } |
| 14070 #endif | 14071 #endif |
| 14071 | 14072 |
| 14072 | 14073 |
| 14073 template<typename Derived, typename Shape, typename Key> | 14074 template<typename Derived, typename Shape, typename Key> |
| 14074 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { | 14075 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 14075 int pos = 0; | 14076 int pos = 0; |
| 14076 int capacity = this->Capacity(); | 14077 int capacity = this->Capacity(); |
| 14077 DisallowHeapAllocation no_gc; | 14078 DisallowHeapAllocation no_gc; |
| 14078 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 14079 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 14079 for (int i = 0; i < capacity; i++) { | 14080 for (int i = 0; i < capacity; i++) { |
| 14080 Object* k = this->KeyAt(i); | 14081 Object* k = this->KeyAt(i); |
| 14081 if (this->IsKey(k)) { | 14082 if (this->IsKey(k)) { |
| 14082 elements->set(pos++, ValueAt(i), mode); | 14083 elements->set(pos++, this->ValueAt(i), mode); |
| 14083 } | 14084 } |
| 14084 } | 14085 } |
| 14085 DCHECK(pos == elements->length()); | 14086 DCHECK(pos == elements->length()); |
| 14086 } | 14087 } |
| 14087 | 14088 |
| 14088 | 14089 |
| 14089 InterceptorInfo* JSObject::GetNamedInterceptor() { | 14090 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 14090 DCHECK(map()->has_named_interceptor()); | 14091 DCHECK(map()->has_named_interceptor()); |
| 14091 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); | 14092 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); |
| 14092 DCHECK(constructor->shared()->IsApiFunction()); | 14093 DCHECK(constructor->shared()->IsApiFunction()); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14247 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { | 14248 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { |
| 14248 if (HasFastProperties()) { | 14249 if (HasFastProperties()) { |
| 14249 Map* map = this->map(); | 14250 Map* map = this->map(); |
| 14250 if (filter == NONE) return map->NumberOfOwnDescriptors(); | 14251 if (filter == NONE) return map->NumberOfOwnDescriptors(); |
| 14251 if (filter & DONT_ENUM) { | 14252 if (filter & DONT_ENUM) { |
| 14252 int result = map->EnumLength(); | 14253 int result = map->EnumLength(); |
| 14253 if (result != kInvalidEnumCacheSentinel) return result; | 14254 if (result != kInvalidEnumCacheSentinel) return result; |
| 14254 } | 14255 } |
| 14255 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); | 14256 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); |
| 14256 } else if (IsGlobalObject()) { | 14257 } else if (IsGlobalObject()) { |
| 14257 return global_dictionary()->NumberOfElementsFilterAttributes(this, filter); | 14258 return global_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 14258 } else { | 14259 } else { |
| 14259 return property_dictionary()->NumberOfElementsFilterAttributes(this, | 14260 return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 14260 filter); | |
| 14261 } | 14261 } |
| 14262 } | 14262 } |
| 14263 | 14263 |
| 14264 | 14264 |
| 14265 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { | 14265 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { |
| 14266 Object* temp = get(i); | 14266 Object* temp = get(i); |
| 14267 set(i, get(j)); | 14267 set(i, get(j)); |
| 14268 set(j, temp); | 14268 set(j, temp); |
| 14269 if (this != numbers) { | 14269 if (this != numbers) { |
| 14270 temp = numbers->get(i); | 14270 temp = numbers->get(i); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14384 if (HasFastProperties()) { | 14384 if (HasFastProperties()) { |
| 14385 int real_size = map()->NumberOfOwnDescriptors(); | 14385 int real_size = map()->NumberOfOwnDescriptors(); |
| 14386 DescriptorArray* descs = map()->instance_descriptors(); | 14386 DescriptorArray* descs = map()->instance_descriptors(); |
| 14387 for (int i = 0; i < real_size; i++) { | 14387 for (int i = 0; i < real_size; i++) { |
| 14388 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 14388 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
| 14389 !FilterKey(descs->GetKey(i), filter)) { | 14389 !FilterKey(descs->GetKey(i), filter)) { |
| 14390 storage->set(index++, descs->GetKey(i)); | 14390 storage->set(index++, descs->GetKey(i)); |
| 14391 } | 14391 } |
| 14392 } | 14392 } |
| 14393 } else if (IsGlobalObject()) { | 14393 } else if (IsGlobalObject()) { |
| 14394 global_dictionary()->CopyKeysTo(this, storage, index, filter, | 14394 global_dictionary()->CopyKeysTo(storage, index, filter, |
| 14395 GlobalDictionary::UNSORTED); | 14395 GlobalDictionary::UNSORTED); |
| 14396 } else { | 14396 } else { |
| 14397 property_dictionary()->CopyKeysTo(this, storage, index, filter, | 14397 property_dictionary()->CopyKeysTo(storage, index, filter, |
| 14398 NameDictionary::UNSORTED); | 14398 NameDictionary::UNSORTED); |
| 14399 } | 14399 } |
| 14400 } | 14400 } |
| 14401 | 14401 |
| 14402 | 14402 |
| 14403 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { | 14403 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { |
| 14404 return GetOwnElementKeys(NULL, filter); | 14404 return GetOwnElementKeys(NULL, filter); |
| 14405 } | 14405 } |
| 14406 | 14406 |
| 14407 | 14407 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14471 storage->set(counter, Smi::FromInt(counter)); | 14471 storage->set(counter, Smi::FromInt(counter)); |
| 14472 } | 14472 } |
| 14473 counter++; | 14473 counter++; |
| 14474 } | 14474 } |
| 14475 DCHECK(!storage || storage->length() >= counter); | 14475 DCHECK(!storage || storage->length() >= counter); |
| 14476 break; | 14476 break; |
| 14477 } | 14477 } |
| 14478 | 14478 |
| 14479 case DICTIONARY_ELEMENTS: { | 14479 case DICTIONARY_ELEMENTS: { |
| 14480 if (storage != NULL) { | 14480 if (storage != NULL) { |
| 14481 element_dictionary()->CopyKeysTo<DictionaryEntryType::kObjects>( | 14481 element_dictionary()->CopyKeysTo(storage, filter, |
| 14482 storage, filter, SeededNumberDictionary::SORTED); | 14482 SeededNumberDictionary::SORTED); |
| 14483 } | 14483 } |
| 14484 counter += | 14484 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 14485 element_dictionary() | |
| 14486 ->NumberOfElementsFilterAttributes<DictionaryEntryType::kObjects>( | |
| 14487 filter); | |
| 14488 break; | 14485 break; |
| 14489 } | 14486 } |
| 14490 case SLOPPY_ARGUMENTS_ELEMENTS: { | 14487 case SLOPPY_ARGUMENTS_ELEMENTS: { |
| 14491 FixedArray* parameter_map = FixedArray::cast(elements()); | 14488 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 14492 int mapped_length = parameter_map->length() - 2; | 14489 int mapped_length = parameter_map->length() - 2; |
| 14493 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 14490 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 14494 if (arguments->IsDictionary()) { | 14491 if (arguments->IsDictionary()) { |
| 14495 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | 14492 // Copy the keys from arguments first, because Dictionary::CopyKeysTo |
| 14496 // will insert in storage starting at index 0. | 14493 // will insert in storage starting at index 0. |
| 14497 SeededNumberDictionary* dictionary = | 14494 SeededNumberDictionary* dictionary = |
| 14498 SeededNumberDictionary::cast(arguments); | 14495 SeededNumberDictionary::cast(arguments); |
| 14499 if (storage != NULL) { | 14496 if (storage != NULL) { |
| 14500 dictionary->CopyKeysTo<DictionaryEntryType::kObjects>( | 14497 dictionary->CopyKeysTo(storage, filter, |
| 14501 storage, filter, SeededNumberDictionary::UNSORTED); | 14498 SeededNumberDictionary::UNSORTED); |
| 14502 } | 14499 } |
| 14503 counter += dictionary->NumberOfElementsFilterAttributes< | 14500 counter += dictionary->NumberOfElementsFilterAttributes(filter); |
| 14504 DictionaryEntryType::kObjects>(filter); | |
| 14505 for (int i = 0; i < mapped_length; ++i) { | 14501 for (int i = 0; i < mapped_length; ++i) { |
| 14506 if (!parameter_map->get(i + 2)->IsTheHole()) { | 14502 if (!parameter_map->get(i + 2)->IsTheHole()) { |
| 14507 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | 14503 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
| 14508 ++counter; | 14504 ++counter; |
| 14509 } | 14505 } |
| 14510 } | 14506 } |
| 14511 if (storage != NULL) storage->SortPairs(storage, counter); | 14507 if (storage != NULL) storage->SortPairs(storage, counter); |
| 14512 | 14508 |
| 14513 } else { | 14509 } else { |
| 14514 int backing_length = arguments->length(); | 14510 int backing_length = arguments->length(); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15159 EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t); | 15155 EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t); |
| 15160 | 15156 |
| 15161 template Handle<UnseededNumberDictionary> | 15157 template Handle<UnseededNumberDictionary> |
| 15162 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | 15158 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 15163 EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t); | 15159 EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t); |
| 15164 | 15160 |
| 15165 template Handle<NameDictionary> | 15161 template Handle<NameDictionary> |
| 15166 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 15162 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
| 15167 EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>); | 15163 EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>); |
| 15168 | 15164 |
| 15169 template bool | 15165 template bool Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 15170 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, | 15166 uint32_t>::HasComplexElements(); |
| 15171 uint32_t>::HasComplexElements<DictionaryEntryType::kCells>(); | |
| 15172 | |
| 15173 template bool | |
| 15174 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, | |
| 15175 uint32_t>::HasComplexElements<DictionaryEntryType::kObjects>(); | |
| 15176 | 15167 |
| 15177 template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, | 15168 template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 15178 uint32_t>::FindEntry(uint32_t); | 15169 uint32_t>::FindEntry(uint32_t); |
| 15179 | 15170 |
| 15180 template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry( | 15171 template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry( |
| 15181 Handle<Name>); | 15172 Handle<Name>); |
| 15182 | 15173 |
| 15183 | 15174 |
| 15184 Handle<Object> JSObject::PrepareSlowElementsForSort( | 15175 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 15185 Handle<JSObject> object, uint32_t limit) { | 15176 Handle<JSObject> object, uint32_t limit) { |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16245 Handle<Object> value) { | 16236 Handle<Object> value) { |
| 16246 int entry = dictionary->FindEntry(key); | 16237 int entry = dictionary->FindEntry(key); |
| 16247 if (entry == kNotFound) return AddNumberEntry(dictionary, key, value); | 16238 if (entry == kNotFound) return AddNumberEntry(dictionary, key, value); |
| 16248 Handle<Object> object_key = | 16239 Handle<Object> object_key = |
| 16249 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); | 16240 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); |
| 16250 dictionary->SetEntry(entry, object_key, value); | 16241 dictionary->SetEntry(entry, object_key, value); |
| 16251 return dictionary; | 16242 return dictionary; |
| 16252 } | 16243 } |
| 16253 | 16244 |
| 16254 | 16245 |
| 16255 template <DictionaryEntryType type, typename D> | |
| 16256 static inline bool IsDeleted(D d, int i) { | |
| 16257 switch (type) { | |
| 16258 case DictionaryEntryType::kObjects: | |
| 16259 return false; | |
| 16260 case DictionaryEntryType::kCells: | |
| 16261 DCHECK(d->ValueAt(i)->IsPropertyCell()); | |
| 16262 return PropertyCell::cast(d->ValueAt(i))->value()->IsTheHole(); | |
| 16263 } | |
| 16264 UNREACHABLE(); | |
| 16265 return false; | |
| 16266 } | |
| 16267 | |
| 16268 | |
| 16269 template <typename Derived, typename Shape, typename Key> | 16246 template <typename Derived, typename Shape, typename Key> |
| 16270 template <DictionaryEntryType type> | |
| 16271 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( | 16247 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 16272 PropertyAttributes filter) { | 16248 PropertyAttributes filter) { |
| 16273 int capacity = this->Capacity(); | 16249 int capacity = this->Capacity(); |
| 16274 int result = 0; | 16250 int result = 0; |
| 16275 for (int i = 0; i < capacity; i++) { | 16251 for (int i = 0; i < capacity; i++) { |
| 16276 Object* k = this->KeyAt(i); | 16252 Object* k = this->KeyAt(i); |
| 16277 if (this->IsKey(k) && !FilterKey(k, filter)) { | 16253 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16278 if (IsDeleted<type>(this, i)) continue; | 16254 if (this->IsDeleted(i)) continue; |
| 16279 PropertyDetails details = DetailsAt(i); | 16255 PropertyDetails details = this->DetailsAt(i); |
| 16280 PropertyAttributes attr = details.attributes(); | 16256 PropertyAttributes attr = details.attributes(); |
| 16281 if ((attr & filter) == 0) result++; | 16257 if ((attr & filter) == 0) result++; |
| 16282 } | 16258 } |
| 16283 } | 16259 } |
| 16284 return result; | 16260 return result; |
| 16285 } | 16261 } |
| 16286 | 16262 |
| 16287 | 16263 |
| 16288 template <typename Derived, typename Shape, typename Key> | 16264 template <typename Derived, typename Shape, typename Key> |
| 16289 template <DictionaryEntryType type> | |
| 16290 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { | 16265 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { |
| 16291 int capacity = this->Capacity(); | 16266 int capacity = this->Capacity(); |
| 16292 for (int i = 0; i < capacity; i++) { | 16267 for (int i = 0; i < capacity; i++) { |
| 16293 Object* k = this->KeyAt(i); | 16268 Object* k = this->KeyAt(i); |
| 16294 if (this->IsKey(k) && !FilterKey(k, NONE)) { | 16269 if (this->IsKey(k) && !FilterKey(k, NONE)) { |
| 16295 if (IsDeleted<type>(this, i)) continue; | 16270 if (this->IsDeleted(i)) continue; |
| 16296 PropertyDetails details = DetailsAt(i); | 16271 PropertyDetails details = this->DetailsAt(i); |
| 16297 if (details.type() == ACCESSOR_CONSTANT) return true; | 16272 if (details.type() == ACCESSOR_CONSTANT) return true; |
| 16298 PropertyAttributes attr = details.attributes(); | 16273 PropertyAttributes attr = details.attributes(); |
| 16299 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; | 16274 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; |
| 16300 } | 16275 } |
| 16301 } | 16276 } |
| 16302 return false; | 16277 return false; |
| 16303 } | 16278 } |
| 16304 | 16279 |
| 16305 | 16280 |
| 16306 template <typename Derived, typename Shape, typename Key> | 16281 template <typename Derived, typename Shape, typename Key> |
| 16307 template <DictionaryEntryType type> | |
| 16308 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 16282 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 16309 FixedArray* storage, PropertyAttributes filter, | 16283 FixedArray* storage, PropertyAttributes filter, |
| 16310 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 16284 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 16311 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); | 16285 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 16312 int capacity = this->Capacity(); | 16286 int capacity = this->Capacity(); |
| 16313 int index = 0; | 16287 int index = 0; |
| 16314 for (int i = 0; i < capacity; i++) { | 16288 for (int i = 0; i < capacity; i++) { |
| 16315 Object* k = this->KeyAt(i); | 16289 Object* k = this->KeyAt(i); |
| 16316 if (this->IsKey(k) && !FilterKey(k, filter)) { | 16290 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16317 if (IsDeleted<type>(this, i)) continue; | 16291 if (this->IsDeleted(i)) continue; |
| 16318 PropertyDetails details = DetailsAt(i); | 16292 PropertyDetails details = this->DetailsAt(i); |
| 16319 PropertyAttributes attr = details.attributes(); | 16293 PropertyAttributes attr = details.attributes(); |
| 16320 if ((attr & filter) == 0) storage->set(index++, k); | 16294 if ((attr & filter) == 0) storage->set(index++, k); |
| 16321 } | 16295 } |
| 16322 } | 16296 } |
| 16323 if (sort_mode == Dictionary::SORTED) { | 16297 if (sort_mode == Dictionary::SORTED) { |
| 16324 storage->SortPairs(storage, index); | 16298 storage->SortPairs(storage, index); |
| 16325 } | 16299 } |
| 16326 DCHECK(storage->length() >= index); | 16300 DCHECK(storage->length() >= index); |
| 16327 } | 16301 } |
| 16328 | 16302 |
| 16329 | 16303 |
| 16330 template <typename Dictionary> | 16304 template <typename Dictionary> |
| 16331 struct EnumIndexComparator { | 16305 struct EnumIndexComparator { |
| 16332 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} | 16306 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} |
| 16333 bool operator() (Smi* a, Smi* b) { | 16307 bool operator() (Smi* a, Smi* b) { |
| 16334 PropertyDetails da(dict->DetailsAt(a->value())); | 16308 PropertyDetails da(dict->DetailsAt(a->value())); |
| 16335 PropertyDetails db(dict->DetailsAt(b->value())); | 16309 PropertyDetails db(dict->DetailsAt(b->value())); |
| 16336 return da.dictionary_index() < db.dictionary_index(); | 16310 return da.dictionary_index() < db.dictionary_index(); |
| 16337 } | 16311 } |
| 16338 Dictionary* dict; | 16312 Dictionary* dict; |
| 16339 }; | 16313 }; |
| 16340 | 16314 |
| 16341 | 16315 |
| 16342 template <typename Derived, typename Shape, typename Key> | 16316 template <typename Derived, typename Shape, typename Key> |
| 16343 template <DictionaryEntryType type> | |
| 16344 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { | 16317 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { |
| 16345 int length = storage->length(); | 16318 int length = storage->length(); |
| 16346 int capacity = this->Capacity(); | 16319 int capacity = this->Capacity(); |
| 16347 int properties = 0; | 16320 int properties = 0; |
| 16348 for (int i = 0; i < capacity; i++) { | 16321 for (int i = 0; i < capacity; i++) { |
| 16349 Object* k = this->KeyAt(i); | 16322 Object* k = this->KeyAt(i); |
| 16350 if (this->IsKey(k) && !k->IsSymbol()) { | 16323 if (this->IsKey(k) && !k->IsSymbol()) { |
| 16351 PropertyDetails details = DetailsAt(i); | 16324 PropertyDetails details = this->DetailsAt(i); |
| 16352 if (details.IsDontEnum() || IsDeleted<type>(this, i)) continue; | 16325 if (details.IsDontEnum() || this->IsDeleted(i)) continue; |
| 16353 storage->set(properties, Smi::FromInt(i)); | 16326 storage->set(properties, Smi::FromInt(i)); |
| 16354 properties++; | 16327 properties++; |
| 16355 if (properties == length) break; | 16328 if (properties == length) break; |
| 16356 } | 16329 } |
| 16357 } | 16330 } |
| 16358 CHECK_EQ(length, properties); | 16331 CHECK_EQ(length, properties); |
| 16359 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); | 16332 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); |
| 16360 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 16333 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 16361 std::sort(start, start + length, cmp); | 16334 std::sort(start, start + length, cmp); |
| 16362 for (int i = 0; i < length; i++) { | 16335 for (int i = 0; i < length; i++) { |
| 16363 int index = Smi::cast(storage->get(i))->value(); | 16336 int index = Smi::cast(storage->get(i))->value(); |
| 16364 storage->set(i, this->KeyAt(index)); | 16337 storage->set(i, this->KeyAt(index)); |
| 16365 } | 16338 } |
| 16366 } | 16339 } |
| 16367 | 16340 |
| 16368 | 16341 |
| 16369 template <typename Derived, typename Shape, typename Key> | 16342 template <typename Derived, typename Shape, typename Key> |
| 16370 template <DictionaryEntryType type> | |
| 16371 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 16343 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 16372 FixedArray* storage, int index, PropertyAttributes filter, | 16344 FixedArray* storage, int index, PropertyAttributes filter, |
| 16373 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 16345 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 16374 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); | 16346 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 16375 int capacity = this->Capacity(); | 16347 int capacity = this->Capacity(); |
| 16376 for (int i = 0; i < capacity; i++) { | 16348 for (int i = 0; i < capacity; i++) { |
| 16377 Object* k = this->KeyAt(i); | 16349 Object* k = this->KeyAt(i); |
| 16378 if (this->IsKey(k) && !FilterKey(k, filter)) { | 16350 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16379 if (IsDeleted<type>(this, i)) continue; | 16351 if (this->IsDeleted(i)) continue; |
| 16380 PropertyDetails details = DetailsAt(i); | 16352 PropertyDetails details = this->DetailsAt(i); |
| 16381 PropertyAttributes attr = details.attributes(); | 16353 PropertyAttributes attr = details.attributes(); |
| 16382 if ((attr & filter) == 0) storage->set(index++, k); | 16354 if ((attr & filter) == 0) storage->set(index++, k); |
| 16383 } | 16355 } |
| 16384 } | 16356 } |
| 16385 if (sort_mode == Dictionary::SORTED) { | 16357 if (sort_mode == Dictionary::SORTED) { |
| 16386 storage->SortPairs(storage, index); | 16358 storage->SortPairs(storage, index); |
| 16387 } | 16359 } |
| 16388 DCHECK(storage->length() >= index); | 16360 DCHECK(storage->length() >= index); |
| 16389 } | 16361 } |
| 16390 | 16362 |
| 16391 | 16363 |
| 16392 // Backwards lookup (slow). | 16364 // Backwards lookup (slow). |
| 16393 template<typename Derived, typename Shape, typename Key> | 16365 template<typename Derived, typename Shape, typename Key> |
| 16394 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 16366 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 16395 int capacity = this->Capacity(); | 16367 int capacity = this->Capacity(); |
| 16396 for (int i = 0; i < capacity; i++) { | 16368 for (int i = 0; i < capacity; i++) { |
| 16397 Object* k = this->KeyAt(i); | 16369 Object* k = this->KeyAt(i); |
| 16398 if (this->IsKey(k)) { | 16370 if (this->IsKey(k)) { |
| 16399 Object* e = ValueAt(i); | 16371 Object* e = this->ValueAt(i); |
| 16400 // TODO(dcarney): this should be templatized. | 16372 // TODO(dcarney): this should be templatized. |
| 16401 if (e->IsPropertyCell()) { | 16373 if (e->IsPropertyCell()) { |
| 16402 e = PropertyCell::cast(e)->value(); | 16374 e = PropertyCell::cast(e)->value(); |
| 16403 } | 16375 } |
| 16404 if (e == value) return k; | 16376 if (e == value) return k; |
| 16405 } | 16377 } |
| 16406 } | 16378 } |
| 16407 Heap* heap = Dictionary::GetHeap(); | 16379 Heap* heap = Dictionary::GetHeap(); |
| 16408 return heap->undefined_value(); | 16380 return heap->undefined_value(); |
| 16409 } | 16381 } |
| (...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17449 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17421 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17450 Handle<Object> new_value) { | 17422 Handle<Object> new_value) { |
| 17451 if (cell->value() != *new_value) { | 17423 if (cell->value() != *new_value) { |
| 17452 cell->set_value(*new_value); | 17424 cell->set_value(*new_value); |
| 17453 Isolate* isolate = cell->GetIsolate(); | 17425 Isolate* isolate = cell->GetIsolate(); |
| 17454 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17426 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17455 isolate, DependentCode::kPropertyCellChangedGroup); | 17427 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17456 } | 17428 } |
| 17457 } | 17429 } |
| 17458 } } // namespace v8::internal | 17430 } } // namespace v8::internal |
| OLD | NEW |