OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 Object* value, | 429 Object* value, |
430 PropertyDetails details) { | 430 PropertyDetails details) { |
431 ASSERT(!HasFastProperties()); | 431 ASSERT(!HasFastProperties()); |
432 int entry = property_dictionary()->FindEntry(name); | 432 int entry = property_dictionary()->FindEntry(name); |
433 if (entry == StringDictionary::kNotFound) { | 433 if (entry == StringDictionary::kNotFound) { |
434 Object* store_value = value; | 434 Object* store_value = value; |
435 if (IsGlobalObject()) { | 435 if (IsGlobalObject()) { |
436 store_value = Heap::AllocateJSGlobalPropertyCell(value); | 436 store_value = Heap::AllocateJSGlobalPropertyCell(value); |
437 if (store_value->IsFailure()) return store_value; | 437 if (store_value->IsFailure()) return store_value; |
438 } | 438 } |
439 Object* dict = | 439 Object* dict = property_dictionary()->Add(name, store_value, details); |
440 property_dictionary()->Add(name, store_value, details); | |
441 if (dict->IsFailure()) return dict; | 440 if (dict->IsFailure()) return dict; |
442 set_properties(StringDictionary::cast(dict)); | 441 set_properties(StringDictionary::cast(dict)); |
443 return value; | 442 return value; |
444 } | 443 } |
445 // Preserve enumeration index. | 444 // Preserve enumeration index. |
446 details = PropertyDetails(details.attributes(), | 445 details = PropertyDetails(details.attributes(), |
447 details.type(), | 446 details.type(), |
448 property_dictionary()->DetailsAt(entry).index()); | 447 property_dictionary()->DetailsAt(entry).index()); |
449 if (IsGlobalObject()) { | 448 if (IsGlobalObject()) { |
450 JSGlobalPropertyCell* cell = | 449 JSGlobalPropertyCell* cell = |
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1705 // occur as fields. | 1704 // occur as fields. |
1706 if (result->IsReadOnly() && result->type() == FIELD && | 1705 if (result->IsReadOnly() && result->type() == FIELD && |
1707 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { | 1706 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { |
1708 result->DisallowCaching(); | 1707 result->DisallowCaching(); |
1709 } | 1708 } |
1710 return; | 1709 return; |
1711 } | 1710 } |
1712 } else { | 1711 } else { |
1713 int entry = property_dictionary()->FindEntry(name); | 1712 int entry = property_dictionary()->FindEntry(name); |
1714 if (entry != StringDictionary::kNotFound) { | 1713 if (entry != StringDictionary::kNotFound) { |
1715 // Make sure to disallow caching for uninitialized constants | |
1716 // found in the dictionary-mode objects. | |
1717 Object* value = property_dictionary()->ValueAt(entry); | 1714 Object* value = property_dictionary()->ValueAt(entry); |
1718 if (IsGlobalObject()) { | 1715 if (IsGlobalObject()) { |
1719 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 1716 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
1720 if (d.IsDeleted()) { | 1717 if (d.IsDeleted()) { |
1721 // We've skipped a global object during lookup, so we cannot | |
1722 // use inline caching because the map of the global object | |
1723 // doesn't change if the property should be re-added. | |
1724 result->DisallowCaching(); | |
1725 result->NotFound(); | 1718 result->NotFound(); |
1726 return; | 1719 return; |
1727 } | 1720 } |
1728 value = JSGlobalPropertyCell::cast(value)->value(); | 1721 value = JSGlobalPropertyCell::cast(value)->value(); |
1729 ASSERT(result->IsLoaded()); | 1722 ASSERT(result->IsLoaded()); |
1730 } | 1723 } |
1731 if (value->IsTheHole()) { | 1724 // Make sure to disallow caching for uninitialized constants |
1732 result->DisallowCaching(); | 1725 // found in the dictionary-mode objects. |
1733 } | 1726 if (value->IsTheHole()) result->DisallowCaching(); |
1734 result->DictionaryResult(this, entry); | 1727 result->DictionaryResult(this, entry); |
1735 return; | 1728 return; |
1736 } | 1729 } |
1737 // Slow case object skipped during lookup. Do not use inline caching. | 1730 // Slow case object skipped during lookup. Do not use inline caching. |
1738 result->DisallowCaching(); | 1731 if (!IsGlobalObject()) result->DisallowCaching(); |
antonm
2009/07/10 09:28:43
maybe move that up, as else clause to if at 1715?
| |
1739 } | 1732 } |
1740 result->NotFound(); | 1733 result->NotFound(); |
1741 } | 1734 } |
1742 | 1735 |
1743 | 1736 |
1744 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { | 1737 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { |
1745 LocalLookupRealNamedProperty(name, result); | 1738 LocalLookupRealNamedProperty(name, result); |
1746 if (result->IsProperty()) return; | 1739 if (result->IsProperty()) return; |
1747 | 1740 |
1748 LookupRealNamedPropertyInPrototypes(name, result); | 1741 LookupRealNamedPropertyInPrototypes(name, result); |
(...skipping 5085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6834 | 6827 |
6835 | 6828 |
6836 Object* GlobalObject::GetPropertyCell(LookupResult* result) { | 6829 Object* GlobalObject::GetPropertyCell(LookupResult* result) { |
6837 ASSERT(!HasFastProperties()); | 6830 ASSERT(!HasFastProperties()); |
6838 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 6831 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
6839 ASSERT(value->IsJSGlobalPropertyCell()); | 6832 ASSERT(value->IsJSGlobalPropertyCell()); |
6840 return value; | 6833 return value; |
6841 } | 6834 } |
6842 | 6835 |
6843 | 6836 |
6837 Object* GlobalObject::EnsurePropertyCell(String* name) { | |
6838 ASSERT(!HasFastProperties()); | |
6839 int entry = property_dictionary()->FindEntry(name); | |
6840 if (entry == StringDictionary::kNotFound) { | |
6841 Object* cell = Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value()); | |
6842 if (cell->IsFailure()) return cell; | |
6843 PropertyDetails details(NONE, NORMAL); | |
6844 details = details.AsDeleted(); | |
6845 Object* dictionary = property_dictionary()->Add(name, cell, details); | |
6846 if (dictionary->IsFailure()) return dictionary; | |
6847 set_properties(StringDictionary::cast(dictionary)); | |
6848 return cell; | |
6849 } else { | |
6850 Object* value = property_dictionary()->ValueAt(entry); | |
6851 ASSERT(value->IsJSGlobalPropertyCell()); | |
6852 return value; | |
6853 } | |
6854 } | |
6855 | |
6856 | |
6844 Object* SymbolTable::LookupString(String* string, Object** s) { | 6857 Object* SymbolTable::LookupString(String* string, Object** s) { |
6845 SymbolKey key(string); | 6858 SymbolKey key(string); |
6846 return LookupKey(&key, s); | 6859 return LookupKey(&key, s); |
6847 } | 6860 } |
6848 | 6861 |
6849 | 6862 |
6850 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { | 6863 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { |
6851 SymbolKey key(string); | 6864 SymbolKey key(string); |
6852 int entry = FindEntry(&key); | 6865 int entry = FindEntry(&key); |
6853 if (entry == kNotFound) { | 6866 if (entry == kNotFound) { |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7193 Object* Dictionary<Shape, Key>::AddEntry(Key key, | 7206 Object* Dictionary<Shape, Key>::AddEntry(Key key, |
7194 Object* value, | 7207 Object* value, |
7195 PropertyDetails details, | 7208 PropertyDetails details, |
7196 uint32_t hash) { | 7209 uint32_t hash) { |
7197 // Compute the key object. | 7210 // Compute the key object. |
7198 Object* k = Shape::AsObject(key); | 7211 Object* k = Shape::AsObject(key); |
7199 if (k->IsFailure()) return k; | 7212 if (k->IsFailure()) return k; |
7200 | 7213 |
7201 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 7214 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); |
7202 // Insert element at empty or deleted entry | 7215 // Insert element at empty or deleted entry |
7203 if (details.index() == 0 && Shape::kIsEnumerable) { | 7216 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { |
7204 // Assign an enumeration index to the property and update | 7217 // Assign an enumeration index to the property and update |
7205 // SetNextEnumerationIndex. | 7218 // SetNextEnumerationIndex. |
7206 int index = NextEnumerationIndex(); | 7219 int index = NextEnumerationIndex(); |
7207 details = PropertyDetails(details.attributes(), details.type(), index); | 7220 details = PropertyDetails(details.attributes(), details.type(), index); |
7208 SetNextEnumerationIndex(index + 1); | 7221 SetNextEnumerationIndex(index + 1); |
7209 } | 7222 } |
7210 SetEntry(entry, k, value, details); | 7223 SetEntry(entry, k, value, details); |
7211 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() | 7224 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() |
7212 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); | 7225 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); |
7213 HashTable<Shape, Key>::ElementAdded(); | 7226 HashTable<Shape, Key>::ElementAdded(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7266 | 7279 |
7267 | 7280 |
7268 template<typename Shape, typename Key> | 7281 template<typename Shape, typename Key> |
7269 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 7282 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
7270 PropertyAttributes filter) { | 7283 PropertyAttributes filter) { |
7271 int capacity = HashTable<Shape, Key>::Capacity(); | 7284 int capacity = HashTable<Shape, Key>::Capacity(); |
7272 int result = 0; | 7285 int result = 0; |
7273 for (int i = 0; i < capacity; i++) { | 7286 for (int i = 0; i < capacity; i++) { |
7274 Object* k = HashTable<Shape, Key>::KeyAt(i); | 7287 Object* k = HashTable<Shape, Key>::KeyAt(i); |
7275 if (HashTable<Shape, Key>::IsKey(k)) { | 7288 if (HashTable<Shape, Key>::IsKey(k)) { |
7276 PropertyAttributes attr = DetailsAt(i).attributes(); | 7289 PropertyDetails details = DetailsAt(i); |
7290 if (details.IsDeleted()) continue; | |
7291 PropertyAttributes attr = details.attributes(); | |
7277 if ((attr & filter) == 0) result++; | 7292 if ((attr & filter) == 0) result++; |
7278 } | 7293 } |
7279 } | 7294 } |
7280 return result; | 7295 return result; |
7281 } | 7296 } |
7282 | 7297 |
7283 | 7298 |
7284 template<typename Shape, typename Key> | 7299 template<typename Shape, typename Key> |
7285 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 7300 int Dictionary<Shape, Key>::NumberOfEnumElements() { |
7286 return NumberOfElementsFilterAttributes( | 7301 return NumberOfElementsFilterAttributes( |
7287 static_cast<PropertyAttributes>(DONT_ENUM)); | 7302 static_cast<PropertyAttributes>(DONT_ENUM)); |
7288 } | 7303 } |
7289 | 7304 |
7290 | 7305 |
7291 template<typename Shape, typename Key> | 7306 template<typename Shape, typename Key> |
7292 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage, | 7307 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage, |
7293 PropertyAttributes filter) { | 7308 PropertyAttributes filter) { |
7294 ASSERT(storage->length() >= NumberOfEnumElements()); | 7309 ASSERT(storage->length() >= NumberOfEnumElements()); |
7295 int capacity = HashTable<Shape, Key>::Capacity(); | 7310 int capacity = HashTable<Shape, Key>::Capacity(); |
7296 int index = 0; | 7311 int index = 0; |
7297 for (int i = 0; i < capacity; i++) { | 7312 for (int i = 0; i < capacity; i++) { |
7298 Object* k = HashTable<Shape, Key>::KeyAt(i); | 7313 Object* k = HashTable<Shape, Key>::KeyAt(i); |
7299 if (HashTable<Shape, Key>::IsKey(k)) { | 7314 if (HashTable<Shape, Key>::IsKey(k)) { |
7300 PropertyAttributes attr = DetailsAt(i).attributes(); | 7315 PropertyDetails details = DetailsAt(i); |
7316 if (details.IsDeleted()) continue; | |
7317 PropertyAttributes attr = details.attributes(); | |
7301 if ((attr & filter) == 0) storage->set(index++, k); | 7318 if ((attr & filter) == 0) storage->set(index++, k); |
7302 } | 7319 } |
7303 } | 7320 } |
7304 storage->SortPairs(storage, index); | 7321 storage->SortPairs(storage, index); |
7305 ASSERT(storage->length() >= index); | 7322 ASSERT(storage->length() >= index); |
7306 } | 7323 } |
7307 | 7324 |
7308 | 7325 |
7309 void StringDictionary::CopyEnumKeysTo(FixedArray* storage, | 7326 void StringDictionary::CopyEnumKeysTo(FixedArray* storage, |
7310 FixedArray* sort_array) { | 7327 FixedArray* sort_array) { |
7311 ASSERT(storage->length() >= NumberOfEnumElements()); | 7328 ASSERT(storage->length() >= NumberOfEnumElements()); |
7312 int capacity = Capacity(); | 7329 int capacity = Capacity(); |
7313 int index = 0; | 7330 int index = 0; |
7314 for (int i = 0; i < capacity; i++) { | 7331 for (int i = 0; i < capacity; i++) { |
7315 Object* k = KeyAt(i); | 7332 Object* k = KeyAt(i); |
7316 if (IsKey(k)) { | 7333 if (IsKey(k)) { |
7317 PropertyDetails details = DetailsAt(i); | 7334 PropertyDetails details = DetailsAt(i); |
7318 if (!details.IsDontEnum()) { | 7335 if (details.IsDeleted() || details.IsDontEnum()) continue; |
7319 storage->set(index, k); | 7336 storage->set(index, k); |
7320 sort_array->set(index, | 7337 sort_array->set(index, |
7321 Smi::FromInt(details.index()), | 7338 Smi::FromInt(details.index()), |
7322 SKIP_WRITE_BARRIER); | 7339 SKIP_WRITE_BARRIER); |
7323 index++; | 7340 index++; |
7324 } | |
7325 } | 7341 } |
7326 } | 7342 } |
7327 storage->SortPairs(sort_array, sort_array->length()); | 7343 storage->SortPairs(sort_array, sort_array->length()); |
7328 ASSERT(storage->length() >= index); | 7344 ASSERT(storage->length() >= index); |
7329 } | 7345 } |
7330 | 7346 |
7331 | 7347 |
7332 template<typename Shape, typename Key> | 7348 template<typename Shape, typename Key> |
7333 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) { | 7349 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) { |
7334 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( | 7350 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( |
7335 static_cast<PropertyAttributes>(NONE))); | 7351 static_cast<PropertyAttributes>(NONE))); |
7336 int capacity = HashTable<Shape, Key>::Capacity(); | 7352 int capacity = HashTable<Shape, Key>::Capacity(); |
7337 int index = 0; | 7353 int index = 0; |
7338 for (int i = 0; i < capacity; i++) { | 7354 for (int i = 0; i < capacity; i++) { |
7339 Object* k = HashTable<Shape, Key>::KeyAt(i); | 7355 Object* k = HashTable<Shape, Key>::KeyAt(i); |
7340 if (HashTable<Shape, Key>::IsKey(k)) { | 7356 if (HashTable<Shape, Key>::IsKey(k)) { |
7357 PropertyDetails details = DetailsAt(i); | |
7358 if (details.IsDeleted()) continue; | |
7341 storage->set(index++, k); | 7359 storage->set(index++, k); |
7342 } | 7360 } |
7343 } | 7361 } |
7344 ASSERT(storage->length() >= index); | 7362 ASSERT(storage->length() >= index); |
7345 } | 7363 } |
7346 | 7364 |
7347 | 7365 |
7348 // Backwards lookup (slow). | 7366 // Backwards lookup (slow). |
7349 template<typename Shape, typename Key> | 7367 template<typename Shape, typename Key> |
7350 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 7368 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7717 if (break_point_objects()->IsUndefined()) return 0; | 7735 if (break_point_objects()->IsUndefined()) return 0; |
7718 // Single beak point. | 7736 // Single beak point. |
7719 if (!break_point_objects()->IsFixedArray()) return 1; | 7737 if (!break_point_objects()->IsFixedArray()) return 1; |
7720 // Multiple break points. | 7738 // Multiple break points. |
7721 return FixedArray::cast(break_point_objects())->length(); | 7739 return FixedArray::cast(break_point_objects())->length(); |
7722 } | 7740 } |
7723 #endif | 7741 #endif |
7724 | 7742 |
7725 | 7743 |
7726 } } // namespace v8::internal | 7744 } } // namespace v8::internal |
OLD | NEW |