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 |