Chromium Code Reviews| 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 |