| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 716 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
| 717 PropertyCell::SetValueInferType(cell, value); | 717 PropertyCell::SetValueInferType(cell, value); |
| 718 // Please note we have to update the property details. | 718 // Please note we have to update the property details. |
| 719 property_dictionary->DetailsAtPut(entry, details); | 719 property_dictionary->DetailsAtPut(entry, details); |
| 720 } else { | 720 } else { |
| 721 property_dictionary->SetEntry(entry, *name, *value, details); | 721 property_dictionary->SetEntry(entry, *name, *value, details); |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 | 724 |
| 725 | 725 |
| 726 // TODO(mstarzinger): Temporary wrapper until target is handlified. | |
| 727 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, | |
| 728 Handle<Name> name) { | |
| 729 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); | |
| 730 } | |
| 731 | |
| 732 | |
| 733 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 726 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 734 Handle<Name> name, | 727 Handle<Name> name, |
| 735 DeleteMode mode) { | 728 DeleteMode mode) { |
| 736 ASSERT(!object->HasFastProperties()); | 729 ASSERT(!object->HasFastProperties()); |
| 737 Isolate* isolate = object->GetIsolate(); | 730 Isolate* isolate = object->GetIsolate(); |
| 738 Handle<NameDictionary> dictionary(object->property_dictionary()); | 731 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 739 int entry = dictionary->FindEntry(*name); | 732 int entry = dictionary->FindEntry(*name); |
| 740 if (entry != NameDictionary::kNotFound) { | 733 if (entry != NameDictionary::kNotFound) { |
| 741 // If we have a global object set the cell to the hole. | 734 // If we have a global object set the cell to the hole. |
| 742 if (object->IsGlobalObject()) { | 735 if (object->IsGlobalObject()) { |
| 743 PropertyDetails details = dictionary->DetailsAt(entry); | 736 PropertyDetails details = dictionary->DetailsAt(entry); |
| 744 if (details.IsDontDelete()) { | 737 if (details.IsDontDelete()) { |
| 745 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 738 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
| 746 // When forced to delete global properties, we have to make a | 739 // When forced to delete global properties, we have to make a |
| 747 // map change to invalidate any ICs that think they can load | 740 // map change to invalidate any ICs that think they can load |
| 748 // from the DontDelete cell without checking if it contains | 741 // from the DontDelete cell without checking if it contains |
| 749 // the hole value. | 742 // the hole value. |
| 750 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 743 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 751 ASSERT(new_map->is_dictionary_map()); | 744 ASSERT(new_map->is_dictionary_map()); |
| 752 object->set_map(*new_map); | 745 object->set_map(*new_map); |
| 753 } | 746 } |
| 754 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 747 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 755 Handle<Object> value = isolate->factory()->the_hole_value(); | 748 Handle<Object> value = isolate->factory()->the_hole_value(); |
| 756 PropertyCell::SetValueInferType(cell, value); | 749 PropertyCell::SetValueInferType(cell, value); |
| 757 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 750 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 758 } else { | 751 } else { |
| 759 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); | 752 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
| 760 if (*deleted == isolate->heap()->true_value()) { | 753 if (*deleted == isolate->heap()->true_value()) { |
| 761 Handle<NameDictionary> new_properties = | 754 Handle<NameDictionary> new_properties = |
| 762 NameDictionaryShrink(dictionary, name); | 755 NameDictionary::Shrink(dictionary, *name); |
| 763 object->set_properties(*new_properties); | 756 object->set_properties(*new_properties); |
| 764 } | 757 } |
| 765 return deleted; | 758 return deleted; |
| 766 } | 759 } |
| 767 } | 760 } |
| 768 return isolate->factory()->true_value(); | 761 return isolate->factory()->true_value(); |
| 769 } | 762 } |
| 770 | 763 |
| 771 | 764 |
| 772 bool JSObject::IsDirty() { | 765 bool JSObject::IsDirty() { |
| (...skipping 12426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13199 } | 13192 } |
| 13200 } | 13193 } |
| 13201 | 13194 |
| 13202 | 13195 |
| 13203 // Certain compilers request function template instantiation when they | 13196 // Certain compilers request function template instantiation when they |
| 13204 // see the definition of the other template functions in the | 13197 // see the definition of the other template functions in the |
| 13205 // class. This requires us to have the template functions put | 13198 // class. This requires us to have the template functions put |
| 13206 // together, so even though this function belongs in objects-debug.cc, | 13199 // together, so even though this function belongs in objects-debug.cc, |
| 13207 // we keep it here instead to satisfy certain compilers. | 13200 // we keep it here instead to satisfy certain compilers. |
| 13208 #ifdef OBJECT_PRINT | 13201 #ifdef OBJECT_PRINT |
| 13209 template<typename Shape, typename Key> | 13202 template<typename Derived, typename Shape, typename Key> |
| 13210 void Dictionary<Shape, Key>::Print(FILE* out) { | 13203 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { |
| 13211 int capacity = HashTable<Shape, Key>::Capacity(); | 13204 int capacity = DerivedHashTable::Capacity(); |
| 13212 for (int i = 0; i < capacity; i++) { | 13205 for (int i = 0; i < capacity; i++) { |
| 13213 Object* k = HashTable<Shape, Key>::KeyAt(i); | 13206 Object* k = DerivedHashTable::KeyAt(i); |
| 13214 if (HashTable<Shape, Key>::IsKey(k)) { | 13207 if (DerivedHashTable::IsKey(k)) { |
| 13215 PrintF(out, " "); | 13208 PrintF(out, " "); |
| 13216 if (k->IsString()) { | 13209 if (k->IsString()) { |
| 13217 String::cast(k)->StringPrint(out); | 13210 String::cast(k)->StringPrint(out); |
| 13218 } else { | 13211 } else { |
| 13219 k->ShortPrint(out); | 13212 k->ShortPrint(out); |
| 13220 } | 13213 } |
| 13221 PrintF(out, ": "); | 13214 PrintF(out, ": "); |
| 13222 ValueAt(i)->ShortPrint(out); | 13215 ValueAt(i)->ShortPrint(out); |
| 13223 PrintF(out, "\n"); | 13216 PrintF(out, "\n"); |
| 13224 } | 13217 } |
| 13225 } | 13218 } |
| 13226 } | 13219 } |
| 13227 #endif | 13220 #endif |
| 13228 | 13221 |
| 13229 | 13222 |
| 13230 template<typename Shape, typename Key> | 13223 template<typename Derived, typename Shape, typename Key> |
| 13231 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13224 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 13232 int pos = 0; | 13225 int pos = 0; |
| 13233 int capacity = HashTable<Shape, Key>::Capacity(); | 13226 int capacity = DerivedHashTable::Capacity(); |
| 13234 DisallowHeapAllocation no_gc; | 13227 DisallowHeapAllocation no_gc; |
| 13235 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13228 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 13236 for (int i = 0; i < capacity; i++) { | 13229 for (int i = 0; i < capacity; i++) { |
| 13237 Object* k = Dictionary<Shape, Key>::KeyAt(i); | 13230 Object* k = Dictionary::KeyAt(i); |
| 13238 if (Dictionary<Shape, Key>::IsKey(k)) { | 13231 if (Dictionary::IsKey(k)) { |
| 13239 elements->set(pos++, ValueAt(i), mode); | 13232 elements->set(pos++, ValueAt(i), mode); |
| 13240 } | 13233 } |
| 13241 } | 13234 } |
| 13242 ASSERT(pos == elements->length()); | 13235 ASSERT(pos == elements->length()); |
| 13243 } | 13236 } |
| 13244 | 13237 |
| 13245 | 13238 |
| 13246 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13239 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 13247 ASSERT(map()->has_named_interceptor()); | 13240 ASSERT(map()->has_named_interceptor()); |
| 13248 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13241 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13932 } | 13925 } |
| 13933 | 13926 |
| 13934 static uint32_t StringHash(Object* obj) { | 13927 static uint32_t StringHash(Object* obj) { |
| 13935 return String::cast(obj)->Hash(); | 13928 return String::cast(obj)->Hash(); |
| 13936 } | 13929 } |
| 13937 | 13930 |
| 13938 String* string_; | 13931 String* string_; |
| 13939 }; | 13932 }; |
| 13940 | 13933 |
| 13941 | 13934 |
| 13942 template<typename Shape, typename Key> | 13935 template<typename Derived, typename Shape, typename Key> |
| 13943 void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { | 13936 void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
| 13944 IteratePointers(v, 0, kElementsStartOffset); | 13937 IteratePointers(v, 0, kElementsStartOffset); |
| 13945 } | 13938 } |
| 13946 | 13939 |
| 13947 | 13940 |
| 13948 template<typename Shape, typename Key> | 13941 template<typename Derived, typename Shape, typename Key> |
| 13949 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 13942 void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) { |
| 13950 IteratePointers(v, | 13943 IteratePointers(v, |
| 13951 kElementsStartOffset, | 13944 kElementsStartOffset, |
| 13952 kHeaderSize + length() * kPointerSize); | 13945 kHeaderSize + length() * kPointerSize); |
| 13953 } | 13946 } |
| 13954 | 13947 |
| 13955 | 13948 |
| 13956 template<typename Shape, typename Key> | 13949 template<typename Derived, typename Shape, typename Key> |
| 13957 MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap, | 13950 MaybeObject* HashTable<Derived, Shape, Key>::Allocate( |
| 13958 int at_least_space_for, | 13951 Heap* heap, |
| 13959 MinimumCapacity capacity_option, | 13952 int at_least_space_for, |
| 13960 PretenureFlag pretenure) { | 13953 MinimumCapacity capacity_option, |
| 13954 PretenureFlag pretenure) { |
| 13961 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 13955 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); |
| 13962 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 13956 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
| 13963 ? at_least_space_for | 13957 ? at_least_space_for |
| 13964 : ComputeCapacity(at_least_space_for); | 13958 : ComputeCapacity(at_least_space_for); |
| 13965 if (capacity > HashTable::kMaxCapacity) { | 13959 if (capacity > HashTable::kMaxCapacity) { |
| 13966 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 13960 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 13967 } | 13961 } |
| 13968 | 13962 |
| 13969 Object* obj; | 13963 Object* obj; |
| 13970 { MaybeObject* maybe_obj = | 13964 { MaybeObject* maybe_obj = |
| 13971 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); | 13965 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); |
| 13972 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13966 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 13973 } | 13967 } |
| 13974 HashTable::cast(obj)->SetNumberOfElements(0); | 13968 HashTable::cast(obj)->SetNumberOfElements(0); |
| 13975 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 13969 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 13976 HashTable::cast(obj)->SetCapacity(capacity); | 13970 HashTable::cast(obj)->SetCapacity(capacity); |
| 13977 return obj; | 13971 return obj; |
| 13978 } | 13972 } |
| 13979 | 13973 |
| 13980 | 13974 |
| 13975 template<typename Derived, typename Shape, typename Key> |
| 13976 Handle<Derived> HashTable<Derived, Shape, Key>::New( |
| 13977 Isolate* isolate, |
| 13978 int at_least_space_for, |
| 13979 MinimumCapacity capacity_option, |
| 13980 PretenureFlag pretenure) { |
| 13981 CALL_HEAP_FUNCTION( |
| 13982 isolate, |
| 13983 Allocate(isolate->heap(), at_least_space_for, capacity_option, pretenure), |
| 13984 Derived); |
| 13985 } |
| 13986 |
| 13987 |
| 13981 // Find entry for key otherwise return kNotFound. | 13988 // Find entry for key otherwise return kNotFound. |
| 13982 int NameDictionary::FindEntry(Name* key) { | 13989 int NameDictionary::FindEntry(Name* key) { |
| 13983 if (!key->IsUniqueName()) { | 13990 if (!key->IsUniqueName()) { |
| 13984 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); | 13991 return DerivedHashTable::FindEntry(key); |
| 13985 } | 13992 } |
| 13986 | 13993 |
| 13987 // Optimized for unique names. Knowledge of the key type allows: | 13994 // Optimized for unique names. Knowledge of the key type allows: |
| 13988 // 1. Move the check if the key is unique out of the loop. | 13995 // 1. Move the check if the key is unique out of the loop. |
| 13989 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 13996 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
| 13990 // 3. Detect a case when a dictionary key is not unique but the key is. | 13997 // 3. Detect a case when a dictionary key is not unique but the key is. |
| 13991 // In case of positive result the dictionary key may be replaced by the | 13998 // In case of positive result the dictionary key may be replaced by the |
| 13992 // internalized string with minimal performance penalty. It gives a chance | 13999 // internalized string with minimal performance penalty. It gives a chance |
| 13993 // to perform further lookups in code stubs (and significant performance | 14000 // to perform further lookups in code stubs (and significant performance |
| 13994 // boost a certain style of code). | 14001 // boost a certain style of code). |
| (...skipping 16 matching lines...) Expand all Loading... |
| 14011 set(index, key); | 14018 set(index, key); |
| 14012 return entry; | 14019 return entry; |
| 14013 } | 14020 } |
| 14014 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); | 14021 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
| 14015 entry = NextProbe(entry, count++, capacity); | 14022 entry = NextProbe(entry, count++, capacity); |
| 14016 } | 14023 } |
| 14017 return kNotFound; | 14024 return kNotFound; |
| 14018 } | 14025 } |
| 14019 | 14026 |
| 14020 | 14027 |
| 14021 template<typename Shape, typename Key> | 14028 template<typename Derived, typename Shape, typename Key> |
| 14022 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 14029 void HashTable<Derived, Shape, Key>::Rehash(Derived* new_table, Key key) { |
| 14023 ASSERT(NumberOfElements() < new_table->Capacity()); | 14030 ASSERT(NumberOfElements() < new_table->Capacity()); |
| 14024 | 14031 |
| 14025 DisallowHeapAllocation no_gc; | 14032 DisallowHeapAllocation no_gc; |
| 14026 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 14033 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
| 14027 | 14034 |
| 14028 // Copy prefix to new array. | 14035 // Copy prefix to new array. |
| 14029 for (int i = kPrefixStartIndex; | 14036 for (int i = kPrefixStartIndex; |
| 14030 i < kPrefixStartIndex + Shape::kPrefixSize; | 14037 i < kPrefixStartIndex + Shape::kPrefixSize; |
| 14031 i++) { | 14038 i++) { |
| 14032 new_table->set(i, get(i), mode); | 14039 new_table->set(i, get(i), mode); |
| 14033 } | 14040 } |
| 14034 | 14041 |
| 14035 // Rehash the elements. | 14042 // Rehash the elements. |
| 14036 int capacity = Capacity(); | 14043 int capacity = Capacity(); |
| 14037 for (int i = 0; i < capacity; i++) { | 14044 for (int i = 0; i < capacity; i++) { |
| 14038 uint32_t from_index = EntryToIndex(i); | 14045 uint32_t from_index = EntryToIndex(i); |
| 14039 Object* k = get(from_index); | 14046 Object* k = get(from_index); |
| 14040 if (IsKey(k)) { | 14047 if (IsKey(k)) { |
| 14041 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 14048 uint32_t hash = HashTable::HashForObject(key, k); |
| 14042 uint32_t insertion_index = | 14049 uint32_t insertion_index = |
| 14043 EntryToIndex(new_table->FindInsertionEntry(hash)); | 14050 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 14044 for (int j = 0; j < Shape::kEntrySize; j++) { | 14051 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14045 new_table->set(insertion_index + j, get(from_index + j), mode); | 14052 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 14046 } | 14053 } |
| 14047 } | 14054 } |
| 14048 } | 14055 } |
| 14049 new_table->SetNumberOfElements(NumberOfElements()); | 14056 new_table->SetNumberOfElements(NumberOfElements()); |
| 14050 new_table->SetNumberOfDeletedElements(0); | 14057 new_table->SetNumberOfDeletedElements(0); |
| 14051 return new_table; | |
| 14052 } | 14058 } |
| 14053 | 14059 |
| 14054 | 14060 |
| 14055 template<typename Shape, typename Key> | 14061 template<typename Derived, typename Shape, typename Key> |
| 14056 uint32_t HashTable<Shape, Key>::EntryForProbe(Key key, | 14062 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( |
| 14057 Object* k, | 14063 Key key, |
| 14058 int probe, | 14064 Object* k, |
| 14059 uint32_t expected) { | 14065 int probe, |
| 14060 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 14066 uint32_t expected) { |
| 14067 uint32_t hash = HashTable::HashForObject(key, k); |
| 14061 uint32_t capacity = Capacity(); | 14068 uint32_t capacity = Capacity(); |
| 14062 uint32_t entry = FirstProbe(hash, capacity); | 14069 uint32_t entry = FirstProbe(hash, capacity); |
| 14063 for (int i = 1; i < probe; i++) { | 14070 for (int i = 1; i < probe; i++) { |
| 14064 if (entry == expected) return expected; | 14071 if (entry == expected) return expected; |
| 14065 entry = NextProbe(entry, i, capacity); | 14072 entry = NextProbe(entry, i, capacity); |
| 14066 } | 14073 } |
| 14067 return entry; | 14074 return entry; |
| 14068 } | 14075 } |
| 14069 | 14076 |
| 14070 | 14077 |
| 14071 template<typename Shape, typename Key> | 14078 template<typename Derived, typename Shape, typename Key> |
| 14072 void HashTable<Shape, Key>::Swap(uint32_t entry1, | 14079 void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1, |
| 14073 uint32_t entry2, | 14080 uint32_t entry2, |
| 14074 WriteBarrierMode mode) { | 14081 WriteBarrierMode mode) { |
| 14075 int index1 = EntryToIndex(entry1); | 14082 int index1 = EntryToIndex(entry1); |
| 14076 int index2 = EntryToIndex(entry2); | 14083 int index2 = EntryToIndex(entry2); |
| 14077 Object* temp[Shape::kEntrySize]; | 14084 Object* temp[Shape::kEntrySize]; |
| 14078 for (int j = 0; j < Shape::kEntrySize; j++) { | 14085 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14079 temp[j] = get(index1 + j); | 14086 temp[j] = get(index1 + j); |
| 14080 } | 14087 } |
| 14081 for (int j = 0; j < Shape::kEntrySize; j++) { | 14088 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14082 set(index1 + j, get(index2 + j), mode); | 14089 set(index1 + j, get(index2 + j), mode); |
| 14083 } | 14090 } |
| 14084 for (int j = 0; j < Shape::kEntrySize; j++) { | 14091 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14085 set(index2 + j, temp[j], mode); | 14092 set(index2 + j, temp[j], mode); |
| 14086 } | 14093 } |
| 14087 } | 14094 } |
| 14088 | 14095 |
| 14089 | 14096 |
| 14090 template<typename Shape, typename Key> | 14097 template<typename Derived, typename Shape, typename Key> |
| 14091 void HashTable<Shape, Key>::Rehash(Key key) { | 14098 void HashTable<Derived, Shape, Key>::Rehash(Key key) { |
| 14092 DisallowHeapAllocation no_gc; | 14099 DisallowHeapAllocation no_gc; |
| 14093 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 14100 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
| 14094 uint32_t capacity = Capacity(); | 14101 uint32_t capacity = Capacity(); |
| 14095 bool done = false; | 14102 bool done = false; |
| 14096 for (int probe = 1; !done; probe++) { | 14103 for (int probe = 1; !done; probe++) { |
| 14097 // All elements at entries given by one of the first _probe_ probes | 14104 // All elements at entries given by one of the first _probe_ probes |
| 14098 // are placed correctly. Other elements might need to be moved. | 14105 // are placed correctly. Other elements might need to be moved. |
| 14099 done = true; | 14106 done = true; |
| 14100 for (uint32_t current = 0; current < capacity; current++) { | 14107 for (uint32_t current = 0; current < capacity; current++) { |
| 14101 Object* current_key = get(EntryToIndex(current)); | 14108 Object* current_key = get(EntryToIndex(current)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 14113 // The place for the current element is occupied. Leave the element | 14120 // The place for the current element is occupied. Leave the element |
| 14114 // for the next probe. | 14121 // for the next probe. |
| 14115 done = false; | 14122 done = false; |
| 14116 } | 14123 } |
| 14117 } | 14124 } |
| 14118 } | 14125 } |
| 14119 } | 14126 } |
| 14120 } | 14127 } |
| 14121 | 14128 |
| 14122 | 14129 |
| 14123 template<typename Shape, typename Key> | 14130 template<typename Derived, typename Shape, typename Key> |
| 14124 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, | 14131 MaybeObject* HashTable<Derived, Shape, Key>::EnsureCapacity( |
| 14125 Key key, | 14132 int n, |
| 14126 PretenureFlag pretenure) { | 14133 Key key, |
| 14134 PretenureFlag pretenure) { |
| 14127 int capacity = Capacity(); | 14135 int capacity = Capacity(); |
| 14128 int nof = NumberOfElements() + n; | 14136 int nof = NumberOfElements() + n; |
| 14129 int nod = NumberOfDeletedElements(); | 14137 int nod = NumberOfDeletedElements(); |
| 14130 // Return if: | 14138 // Return if: |
| 14131 // 50% is still free after adding n elements and | 14139 // 50% is still free after adding n elements and |
| 14132 // at most 50% of the free elements are deleted elements. | 14140 // at most 50% of the free elements are deleted elements. |
| 14133 if (nod <= (capacity - nof) >> 1) { | 14141 if (nod <= (capacity - nof) >> 1) { |
| 14134 int needed_free = nof >> 1; | 14142 int needed_free = nof >> 1; |
| 14135 if (nof + needed_free <= capacity) return this; | 14143 if (nof + needed_free <= capacity) return this; |
| 14136 } | 14144 } |
| 14137 | 14145 |
| 14138 const int kMinCapacityForPretenure = 256; | 14146 const int kMinCapacityForPretenure = 256; |
| 14139 bool should_pretenure = pretenure == TENURED || | 14147 bool should_pretenure = pretenure == TENURED || |
| 14140 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); | 14148 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
| 14141 Object* obj; | 14149 Object* obj; |
| 14142 { MaybeObject* maybe_obj = | 14150 { MaybeObject* maybe_obj = |
| 14143 Allocate(GetHeap(), | 14151 Allocate(GetHeap(), |
| 14144 nof * 2, | 14152 nof * 2, |
| 14145 USE_DEFAULT_MINIMUM_CAPACITY, | 14153 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14146 should_pretenure ? TENURED : NOT_TENURED); | 14154 should_pretenure ? TENURED : NOT_TENURED); |
| 14147 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 14155 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 14148 } | 14156 } |
| 14149 | 14157 |
| 14150 return Rehash(HashTable::cast(obj), key); | 14158 Rehash(Derived::cast(obj), key); |
| 14159 return Derived::cast(obj); |
| 14151 } | 14160 } |
| 14152 | 14161 |
| 14153 | 14162 |
| 14154 template<typename Shape, typename Key> | 14163 template<typename Derived, typename Shape, typename Key> |
| 14155 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 14164 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, |
| 14156 int capacity = Capacity(); | 14165 Key key) { |
| 14157 int nof = NumberOfElements(); | 14166 int capacity = table->Capacity(); |
| 14167 int nof = table->NumberOfElements(); |
| 14158 | 14168 |
| 14159 // Shrink to fit the number of elements if only a quarter of the | 14169 // Shrink to fit the number of elements if only a quarter of the |
| 14160 // capacity is filled with elements. | 14170 // capacity is filled with elements. |
| 14161 if (nof > (capacity >> 2)) return this; | 14171 if (nof > (capacity >> 2)) return table; |
| 14162 // Allocate a new dictionary with room for at least the current | 14172 // Allocate a new dictionary with room for at least the current |
| 14163 // number of elements. The allocation method will make sure that | 14173 // number of elements. The allocation method will make sure that |
| 14164 // there is extra room in the dictionary for additions. Don't go | 14174 // there is extra room in the dictionary for additions. Don't go |
| 14165 // lower than room for 16 elements. | 14175 // lower than room for 16 elements. |
| 14166 int at_least_room_for = nof; | 14176 int at_least_room_for = nof; |
| 14167 if (at_least_room_for < 16) return this; | 14177 if (at_least_room_for < 16) return table; |
| 14168 | 14178 |
| 14179 Isolate* isolate = table->GetIsolate(); |
| 14169 const int kMinCapacityForPretenure = 256; | 14180 const int kMinCapacityForPretenure = 256; |
| 14170 bool pretenure = | 14181 bool pretenure = |
| 14171 (at_least_room_for > kMinCapacityForPretenure) && | 14182 (at_least_room_for > kMinCapacityForPretenure) && |
| 14172 !GetHeap()->InNewSpace(this); | 14183 !isolate->heap()->InNewSpace(*table); |
| 14173 Object* obj; | 14184 Handle<Derived> new_table = New( |
| 14174 { MaybeObject* maybe_obj = | 14185 isolate, |
| 14175 Allocate(GetHeap(), | 14186 at_least_room_for, |
| 14176 at_least_room_for, | 14187 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14177 USE_DEFAULT_MINIMUM_CAPACITY, | 14188 pretenure ? TENURED : NOT_TENURED); |
| 14178 pretenure ? TENURED : NOT_TENURED); | |
| 14179 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 14180 } | |
| 14181 | 14189 |
| 14182 return Rehash(HashTable::cast(obj), key); | 14190 table->Rehash(*new_table, key); |
| 14191 return new_table; |
| 14183 } | 14192 } |
| 14184 | 14193 |
| 14185 | 14194 |
| 14186 template<typename Shape, typename Key> | 14195 template<typename Derived, typename Shape, typename Key> |
| 14187 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 14196 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { |
| 14188 uint32_t capacity = Capacity(); | 14197 uint32_t capacity = Capacity(); |
| 14189 uint32_t entry = FirstProbe(hash, capacity); | 14198 uint32_t entry = FirstProbe(hash, capacity); |
| 14190 uint32_t count = 1; | 14199 uint32_t count = 1; |
| 14191 // EnsureCapacity will guarantee the hash table is never full. | 14200 // EnsureCapacity will guarantee the hash table is never full. |
| 14192 while (true) { | 14201 while (true) { |
| 14193 Object* element = KeyAt(entry); | 14202 Object* element = KeyAt(entry); |
| 14194 if (element->IsUndefined() || element->IsTheHole()) break; | 14203 if (element->IsUndefined() || element->IsTheHole()) break; |
| 14195 entry = NextProbe(entry, count++, capacity); | 14204 entry = NextProbe(entry, count++, capacity); |
| 14196 } | 14205 } |
| 14197 return entry; | 14206 return entry; |
| 14198 } | 14207 } |
| 14199 | 14208 |
| 14200 | 14209 |
| 14201 // Force instantiation of template instances class. | 14210 // Force instantiation of template instances class. |
| 14202 // Please note this list is compiler dependent. | 14211 // Please note this list is compiler dependent. |
| 14203 | 14212 |
| 14204 template class HashTable<StringTableShape, HashTableKey*>; | 14213 template class HashTable<StringTable, StringTableShape, HashTableKey*>; |
| 14205 | 14214 |
| 14206 template class HashTable<CompilationCacheShape, HashTableKey*>; | 14215 template class HashTable<CompilationCacheTable, |
| 14216 CompilationCacheShape, |
| 14217 HashTableKey*>; |
| 14207 | 14218 |
| 14208 template class HashTable<MapCacheShape, HashTableKey*>; | 14219 template class HashTable<MapCache, MapCacheShape, HashTableKey*>; |
| 14209 | 14220 |
| 14210 template class HashTable<ObjectHashTableShape, Object*>; | 14221 template class HashTable<ObjectHashTable, ObjectHashTableShape, Object*>; |
| 14211 | 14222 |
| 14212 template class HashTable<WeakHashTableShape<2>, Object*>; | 14223 template class HashTable<WeakHashTable, WeakHashTableShape<2>, Object*>; |
| 14213 | 14224 |
| 14214 template class Dictionary<NameDictionaryShape, Name*>; | 14225 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; |
| 14215 | 14226 |
| 14216 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 14227 template class Dictionary<SeededNumberDictionary, |
| 14228 SeededNumberDictionaryShape, |
| 14229 uint32_t>; |
| 14217 | 14230 |
| 14218 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 14231 template class Dictionary<UnseededNumberDictionary, |
| 14232 UnseededNumberDictionaryShape, |
| 14233 uint32_t>; |
| 14219 | 14234 |
| 14220 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14235 template MaybeObject* |
| 14236 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14221 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14237 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14222 | 14238 |
| 14223 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14239 template MaybeObject* |
| 14240 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14224 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14241 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14225 | 14242 |
| 14226 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14243 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14227 Allocate(Heap* heap, int n, PretenureFlag pretenure); | 14244 Allocate(Heap* heap, int n, PretenureFlag pretenure); |
| 14228 | 14245 |
| 14229 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( | 14246 template MaybeObject* |
| 14230 uint32_t, Object*); | 14247 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14231 | |
| 14232 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | |
| 14233 AtPut(uint32_t, Object*); | 14248 AtPut(uint32_t, Object*); |
| 14234 | 14249 |
| 14235 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14250 template MaybeObject* |
| 14251 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14252 AtPut(uint32_t, Object*); |
| 14253 |
| 14254 template Object* |
| 14255 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14236 SlowReverseLookup(Object* value); | 14256 SlowReverseLookup(Object* value); |
| 14237 | 14257 |
| 14238 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14258 template Object* |
| 14259 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14239 SlowReverseLookup(Object* value); | 14260 SlowReverseLookup(Object* value); |
| 14240 | 14261 |
| 14241 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( | 14262 template Object* |
| 14263 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SlowReverseLookup( |
| 14242 Object*); | 14264 Object*); |
| 14243 | 14265 |
| 14244 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( | 14266 template void |
| 14245 FixedArray*, | 14267 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14246 PropertyAttributes, | 14268 CopyKeysTo( |
| 14247 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); | 14269 FixedArray*, |
| 14270 PropertyAttributes, |
| 14271 Dictionary<SeededNumberDictionary, |
| 14272 SeededNumberDictionaryShape, |
| 14273 uint32_t>::SortMode); |
| 14248 | 14274 |
| 14249 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14275 template Object* |
| 14276 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14250 int, JSObject::DeleteMode); | 14277 int, JSObject::DeleteMode); |
| 14251 | 14278 |
| 14252 template Handle<Object> Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14279 template Handle<Object> |
| 14253 Handle<Dictionary<NameDictionaryShape, Name*> >, | 14280 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14281 Handle<Dictionary<NameDictionary, NameDictionaryShape, Name*> >, |
| 14254 int, | 14282 int, |
| 14255 JSObject::DeleteMode); | 14283 JSObject::DeleteMode); |
| 14256 | 14284 |
| 14257 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14285 template Object* |
| 14286 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14258 DeleteProperty(int, JSObject::DeleteMode); | 14287 DeleteProperty(int, JSObject::DeleteMode); |
| 14259 | 14288 |
| 14260 template Handle<Object> | 14289 template Handle<Object> |
| 14261 Dictionary<SeededNumberDictionaryShape, uint32_t>::DeleteProperty( | 14290 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14262 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | 14291 DeleteProperty( |
| 14263 int, | 14292 Handle<Dictionary<SeededNumberDictionary, |
| 14264 JSObject::DeleteMode); | 14293 SeededNumberDictionaryShape, |
| 14294 uint32_t> >, |
| 14295 int, |
| 14296 JSObject::DeleteMode); |
| 14265 | 14297 |
| 14266 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); | 14298 template Handle<NameDictionary> |
| 14299 HashTable<NameDictionary, NameDictionaryShape, Name*>:: |
| 14300 Shrink(Handle<NameDictionary>, Name* n); |
| 14267 | 14301 |
| 14268 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14302 template Handle<SeededNumberDictionary> |
| 14269 uint32_t); | 14303 HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14270 template Handle<FixedArray> | 14304 Shrink(Handle<SeededNumberDictionary>, uint32_t); |
| 14271 Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | |
| 14272 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | |
| 14273 uint32_t); | |
| 14274 | 14305 |
| 14275 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( | 14306 template void Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14276 FixedArray*, | 14307 CopyKeysTo( |
| 14277 int, | 14308 FixedArray*, |
| 14278 PropertyAttributes, | 14309 int, |
| 14279 Dictionary<NameDictionaryShape, Name*>::SortMode); | 14310 PropertyAttributes, |
| 14311 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SortMode); |
| 14280 | 14312 |
| 14281 template int | 14313 template int |
| 14282 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( | 14314 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14283 PropertyAttributes); | 14315 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14284 | 14316 |
| 14285 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( | 14317 template MaybeObject* |
| 14318 Dictionary<NameDictionary, NameDictionaryShape, Name*>::Add( |
| 14286 Name*, Object*, PropertyDetails); | 14319 Name*, Object*, PropertyDetails); |
| 14287 | 14320 |
| 14288 template MaybeObject* | 14321 template MaybeObject* |
| 14289 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); | 14322 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14323 GenerateNewEnumerationIndices(); |
| 14290 | 14324 |
| 14291 template int | 14325 template int |
| 14292 Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14326 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14293 NumberOfElementsFilterAttributes(PropertyAttributes); | 14327 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14294 | 14328 |
| 14295 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( | 14329 template MaybeObject* |
| 14330 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add( |
| 14296 uint32_t, Object*, PropertyDetails); | 14331 uint32_t, Object*, PropertyDetails); |
| 14297 | 14332 |
| 14298 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( | 14333 template MaybeObject* |
| 14299 uint32_t, Object*, PropertyDetails); | 14334 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14335 Add(uint32_t, Object*, PropertyDetails); |
| 14300 | 14336 |
| 14301 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14337 template MaybeObject* |
| 14338 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14302 EnsureCapacity(int, uint32_t); | 14339 EnsureCapacity(int, uint32_t); |
| 14303 | 14340 |
| 14304 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14341 template MaybeObject* |
| 14342 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14305 EnsureCapacity(int, uint32_t); | 14343 EnsureCapacity(int, uint32_t); |
| 14306 | 14344 |
| 14307 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14345 template MaybeObject* |
| 14346 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14308 EnsureCapacity(int, Name*); | 14347 EnsureCapacity(int, Name*); |
| 14309 | 14348 |
| 14310 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14349 template MaybeObject* |
| 14350 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14311 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14351 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14312 | 14352 |
| 14313 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14353 template MaybeObject* |
| 14354 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14314 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14355 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14315 | 14356 |
| 14316 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( | 14357 template MaybeObject* |
| 14358 Dictionary<NameDictionary, NameDictionaryShape, Name*>::AddEntry( |
| 14317 Name*, Object*, PropertyDetails, uint32_t); | 14359 Name*, Object*, PropertyDetails, uint32_t); |
| 14318 | 14360 |
| 14319 template | 14361 template |
| 14320 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 14362 int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14363 NumberOfEnumElements(); |
| 14321 | 14364 |
| 14322 template | 14365 template |
| 14323 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); | 14366 int Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14367 NumberOfEnumElements(); |
| 14324 | 14368 |
| 14325 template | 14369 template |
| 14326 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 14370 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14371 FindEntry(uint32_t); |
| 14327 | 14372 |
| 14328 | 14373 |
| 14329 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14374 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 14330 Handle<JSObject> object, uint32_t limit) { | 14375 Handle<JSObject> object, uint32_t limit) { |
| 14331 CALL_HEAP_FUNCTION(object->GetIsolate(), | 14376 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 14332 object->PrepareSlowElementsForSort(limit), | 14377 object->PrepareSlowElementsForSort(limit), |
| 14333 Object); | 14378 Object); |
| 14334 } | 14379 } |
| 14335 | 14380 |
| 14336 | 14381 |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15162 | 15207 |
| 15163 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15208 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| 15164 int entry = cache->FindInsertionEntry(key.Hash()); | 15209 int entry = cache->FindInsertionEntry(key.Hash()); |
| 15165 cache->set(EntryToIndex(entry), array); | 15210 cache->set(EntryToIndex(entry), array); |
| 15166 cache->set(EntryToIndex(entry) + 1, value); | 15211 cache->set(EntryToIndex(entry) + 1, value); |
| 15167 cache->ElementAdded(); | 15212 cache->ElementAdded(); |
| 15168 return cache; | 15213 return cache; |
| 15169 } | 15214 } |
| 15170 | 15215 |
| 15171 | 15216 |
| 15172 template<typename Shape, typename Key> | 15217 template<typename Derived, typename Shape, typename Key> |
| 15173 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, | 15218 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( |
| 15174 int at_least_space_for, | 15219 Heap* heap, |
| 15175 PretenureFlag pretenure) { | 15220 int at_least_space_for, |
| 15221 PretenureFlag pretenure) { |
| 15176 Object* obj; | 15222 Object* obj; |
| 15177 { MaybeObject* maybe_obj = | 15223 { MaybeObject* maybe_obj = |
| 15178 HashTable<Shape, Key>::Allocate( | 15224 DerivedHashTable::Allocate( |
| 15179 heap, | 15225 heap, |
| 15180 at_least_space_for, | 15226 at_least_space_for, |
| 15181 USE_DEFAULT_MINIMUM_CAPACITY, | 15227 USE_DEFAULT_MINIMUM_CAPACITY, |
| 15182 pretenure); | 15228 pretenure); |
| 15183 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15229 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15184 } | 15230 } |
| 15185 // Initialize the next enumeration index. | 15231 // Initialize the next enumeration index. |
| 15186 Dictionary<Shape, Key>::cast(obj)-> | 15232 Dictionary::cast(obj)-> |
| 15187 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15233 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 15188 return obj; | 15234 return obj; |
| 15189 } | 15235 } |
| 15190 | 15236 |
| 15191 | 15237 |
| 15192 void NameDictionary::DoGenerateNewEnumerationIndices( | 15238 void NameDictionary::DoGenerateNewEnumerationIndices( |
| 15193 Handle<NameDictionary> dictionary) { | 15239 Handle<NameDictionary> dictionary) { |
| 15194 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 15240 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
| 15195 dictionary->GenerateNewEnumerationIndices()); | 15241 dictionary->GenerateNewEnumerationIndices()); |
| 15196 } | 15242 } |
| 15197 | 15243 |
| 15198 template<typename Shape, typename Key> | 15244 template<typename Derived, typename Shape, typename Key> |
| 15199 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 15245 MaybeObject* Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices() { |
| 15200 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15246 Heap* heap = Dictionary::GetHeap(); |
| 15201 int length = HashTable<Shape, Key>::NumberOfElements(); | 15247 int length = DerivedHashTable::NumberOfElements(); |
| 15202 | 15248 |
| 15203 // Allocate and initialize iteration order array. | 15249 // Allocate and initialize iteration order array. |
| 15204 Object* obj; | 15250 Object* obj; |
| 15205 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15251 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15206 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15252 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15207 } | 15253 } |
| 15208 FixedArray* iteration_order = FixedArray::cast(obj); | 15254 FixedArray* iteration_order = FixedArray::cast(obj); |
| 15209 for (int i = 0; i < length; i++) { | 15255 for (int i = 0; i < length; i++) { |
| 15210 iteration_order->set(i, Smi::FromInt(i)); | 15256 iteration_order->set(i, Smi::FromInt(i)); |
| 15211 } | 15257 } |
| 15212 | 15258 |
| 15213 // Allocate array with enumeration order. | 15259 // Allocate array with enumeration order. |
| 15214 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15260 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15215 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15261 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15216 } | 15262 } |
| 15217 FixedArray* enumeration_order = FixedArray::cast(obj); | 15263 FixedArray* enumeration_order = FixedArray::cast(obj); |
| 15218 | 15264 |
| 15219 // Fill the enumeration order array with property details. | 15265 // Fill the enumeration order array with property details. |
| 15220 int capacity = HashTable<Shape, Key>::Capacity(); | 15266 int capacity = DerivedHashTable::Capacity(); |
| 15221 int pos = 0; | 15267 int pos = 0; |
| 15222 for (int i = 0; i < capacity; i++) { | 15268 for (int i = 0; i < capacity; i++) { |
| 15223 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15269 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15224 int index = DetailsAt(i).dictionary_index(); | 15270 int index = DetailsAt(i).dictionary_index(); |
| 15225 enumeration_order->set(pos++, Smi::FromInt(index)); | 15271 enumeration_order->set(pos++, Smi::FromInt(index)); |
| 15226 } | 15272 } |
| 15227 } | 15273 } |
| 15228 | 15274 |
| 15229 // Sort the arrays wrt. enumeration order. | 15275 // Sort the arrays wrt. enumeration order. |
| 15230 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); | 15276 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); |
| 15231 | 15277 |
| 15232 // Overwrite the enumeration_order with the enumeration indices. | 15278 // Overwrite the enumeration_order with the enumeration indices. |
| 15233 for (int i = 0; i < length; i++) { | 15279 for (int i = 0; i < length; i++) { |
| 15234 int index = Smi::cast(iteration_order->get(i))->value(); | 15280 int index = Smi::cast(iteration_order->get(i))->value(); |
| 15235 int enum_index = PropertyDetails::kInitialIndex + i; | 15281 int enum_index = PropertyDetails::kInitialIndex + i; |
| 15236 enumeration_order->set(index, Smi::FromInt(enum_index)); | 15282 enumeration_order->set(index, Smi::FromInt(enum_index)); |
| 15237 } | 15283 } |
| 15238 | 15284 |
| 15239 // Update the dictionary with new indices. | 15285 // Update the dictionary with new indices. |
| 15240 capacity = HashTable<Shape, Key>::Capacity(); | 15286 capacity = DerivedHashTable::Capacity(); |
| 15241 pos = 0; | 15287 pos = 0; |
| 15242 for (int i = 0; i < capacity; i++) { | 15288 for (int i = 0; i < capacity; i++) { |
| 15243 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15289 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15244 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 15290 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
| 15245 PropertyDetails details = DetailsAt(i); | 15291 PropertyDetails details = DetailsAt(i); |
| 15246 PropertyDetails new_details = PropertyDetails( | 15292 PropertyDetails new_details = PropertyDetails( |
| 15247 details.attributes(), details.type(), enum_index); | 15293 details.attributes(), details.type(), enum_index); |
| 15248 DetailsAtPut(i, new_details); | 15294 DetailsAtPut(i, new_details); |
| 15249 } | 15295 } |
| 15250 } | 15296 } |
| 15251 | 15297 |
| 15252 // Set the next enumeration index. | 15298 // Set the next enumeration index. |
| 15253 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 15299 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
| 15254 return this; | 15300 return this; |
| 15255 } | 15301 } |
| 15256 | 15302 |
| 15257 template<typename Shape, typename Key> | 15303 template<typename Derived, typename Shape, typename Key> |
| 15258 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { | 15304 MaybeObject* Dictionary<Derived, Shape, Key>::EnsureCapacity(int n, Key key) { |
| 15259 // Check whether there are enough enumeration indices to add n elements. | 15305 // Check whether there are enough enumeration indices to add n elements. |
| 15260 if (Shape::kIsEnumerable && | 15306 if (Shape::kIsEnumerable && |
| 15261 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 15307 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
| 15262 // If not, we generate new indices for the properties. | 15308 // If not, we generate new indices for the properties. |
| 15263 Object* result; | 15309 Object* result; |
| 15264 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15310 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 15265 if (!maybe_result->ToObject(&result)) return maybe_result; | 15311 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 15266 } | 15312 } |
| 15267 } | 15313 } |
| 15268 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 15314 return DerivedHashTable::EnsureCapacity(n, key); |
| 15269 } | 15315 } |
| 15270 | 15316 |
| 15271 | 15317 |
| 15272 // TODO(ishell): Temporary wrapper until handlified. | 15318 // TODO(ishell): Temporary wrapper until handlified. |
| 15273 template<typename Shape, typename Key> | 15319 template<typename Derived, typename Shape, typename Key> |
| 15274 Handle<Object> Dictionary<Shape, Key>::DeleteProperty( | 15320 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15275 Handle<Dictionary<Shape, Key> > dictionary, | 15321 Handle<Dictionary<Derived, Shape, Key> > dictionary, |
| 15276 int entry, | 15322 int entry, |
| 15277 JSObject::DeleteMode mode) { | 15323 JSObject::DeleteMode mode) { |
| 15278 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15324 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15279 dictionary->DeleteProperty(entry, mode), | 15325 dictionary->DeleteProperty(entry, mode), |
| 15280 Object); | 15326 Object); |
| 15281 } | 15327 } |
| 15282 | 15328 |
| 15283 | 15329 |
| 15284 template<typename Shape, typename Key> | 15330 template<typename Derived, typename Shape, typename Key> |
| 15285 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 15331 Object* Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15286 JSReceiver::DeleteMode mode) { | 15332 int entry, |
| 15287 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15333 JSReceiver::DeleteMode mode) { |
| 15334 Heap* heap = Dictionary::GetHeap(); |
| 15288 PropertyDetails details = DetailsAt(entry); | 15335 PropertyDetails details = DetailsAt(entry); |
| 15289 // Ignore attributes if forcing a deletion. | 15336 // Ignore attributes if forcing a deletion. |
| 15290 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 15337 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
| 15291 return heap->false_value(); | 15338 return heap->false_value(); |
| 15292 } | 15339 } |
| 15293 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); | 15340 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
| 15294 HashTable<Shape, Key>::ElementRemoved(); | 15341 DerivedHashTable::ElementRemoved(); |
| 15295 return heap->true_value(); | 15342 return heap->true_value(); |
| 15296 } | 15343 } |
| 15297 | 15344 |
| 15298 | 15345 |
| 15299 // TODO(ishell): Temporary wrapper until handlified. | 15346 template<typename Derived, typename Shape, typename Key> |
| 15300 template<typename Shape, typename Key> | 15347 MaybeObject* Dictionary<Derived, Shape, Key>::AtPut(Key key, Object* value) { |
| 15301 Handle<FixedArray> Dictionary<Shape, Key>::Shrink( | |
| 15302 Handle<Dictionary<Shape, Key> > dictionary, | |
| 15303 Key key) { | |
| 15304 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | |
| 15305 dictionary->Shrink(key), | |
| 15306 FixedArray); | |
| 15307 } | |
| 15308 | |
| 15309 | |
| 15310 template<typename Shape, typename Key> | |
| 15311 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { | |
| 15312 return HashTable<Shape, Key>::Shrink(key); | |
| 15313 } | |
| 15314 | |
| 15315 | |
| 15316 template<typename Shape, typename Key> | |
| 15317 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | |
| 15318 int entry = this->FindEntry(key); | 15348 int entry = this->FindEntry(key); |
| 15319 | 15349 |
| 15320 // If the entry is present set the value; | 15350 // If the entry is present set the value; |
| 15321 if (entry != Dictionary<Shape, Key>::kNotFound) { | 15351 if (entry != Dictionary::kNotFound) { |
| 15322 ValueAtPut(entry, value); | 15352 ValueAtPut(entry, value); |
| 15323 return this; | 15353 return this; |
| 15324 } | 15354 } |
| 15325 | 15355 |
| 15326 // Check whether the dictionary should be extended. | 15356 // Check whether the dictionary should be extended. |
| 15327 Object* obj; | 15357 Object* obj; |
| 15328 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15358 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15329 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15359 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15330 } | 15360 } |
| 15331 | 15361 |
| 15332 Object* k; | 15362 Object* k; |
| 15333 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15363 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15334 if (!maybe_k->ToObject(&k)) return maybe_k; | 15364 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15335 } | 15365 } |
| 15336 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); | 15366 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); |
| 15337 | 15367 |
| 15338 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15368 return Dictionary::cast(obj)->AddEntry( |
| 15339 Dictionary<Shape, Key>::Hash(key)); | 15369 key, value, details, Dictionary::Hash(key)); |
| 15340 } | 15370 } |
| 15341 | 15371 |
| 15342 | 15372 |
| 15343 template<typename Shape, typename Key> | 15373 template<typename Derived, typename Shape, typename Key> |
| 15344 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 15374 MaybeObject* Dictionary<Derived, Shape, Key>::Add( |
| 15345 Object* value, | 15375 Key key, |
| 15346 PropertyDetails details) { | 15376 Object* value, |
| 15377 PropertyDetails details) { |
| 15347 // Valdate key is absent. | 15378 // Valdate key is absent. |
| 15348 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 15379 SLOW_ASSERT((this->FindEntry(key) == Dictionary::kNotFound)); |
| 15349 // Check whether the dictionary should be extended. | 15380 // Check whether the dictionary should be extended. |
| 15350 Object* obj; | 15381 Object* obj; |
| 15351 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15382 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15352 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15383 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15353 } | 15384 } |
| 15354 | 15385 |
| 15355 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15386 return Dictionary::cast(obj)->AddEntry( |
| 15356 Dictionary<Shape, Key>::Hash(key)); | 15387 key, value, details, Dictionary::Hash(key)); |
| 15357 } | 15388 } |
| 15358 | 15389 |
| 15359 | 15390 |
| 15360 // Add a key, value pair to the dictionary. | 15391 // Add a key, value pair to the dictionary. |
| 15361 template<typename Shape, typename Key> | 15392 template<typename Derived, typename Shape, typename Key> |
| 15362 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 15393 MaybeObject* Dictionary<Derived, Shape, Key>::AddEntry( |
| 15363 Object* value, | 15394 Key key, |
| 15364 PropertyDetails details, | 15395 Object* value, |
| 15365 uint32_t hash) { | 15396 PropertyDetails details, |
| 15397 uint32_t hash) { |
| 15366 // Compute the key object. | 15398 // Compute the key object. |
| 15367 Object* k; | 15399 Object* k; |
| 15368 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15400 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15369 if (!maybe_k->ToObject(&k)) return maybe_k; | 15401 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15370 } | 15402 } |
| 15371 | 15403 |
| 15372 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 15404 uint32_t entry = Dictionary::FindInsertionEntry(hash); |
| 15373 // Insert element at empty or deleted entry | 15405 // Insert element at empty or deleted entry |
| 15374 if (!details.IsDeleted() && | 15406 if (!details.IsDeleted() && |
| 15375 details.dictionary_index() == 0 && | 15407 details.dictionary_index() == 0 && |
| 15376 Shape::kIsEnumerable) { | 15408 Shape::kIsEnumerable) { |
| 15377 // Assign an enumeration index to the property and update | 15409 // Assign an enumeration index to the property and update |
| 15378 // SetNextEnumerationIndex. | 15410 // SetNextEnumerationIndex. |
| 15379 int index = NextEnumerationIndex(); | 15411 int index = NextEnumerationIndex(); |
| 15380 details = PropertyDetails(details.attributes(), details.type(), index); | 15412 details = PropertyDetails(details.attributes(), details.type(), index); |
| 15381 SetNextEnumerationIndex(index + 1); | 15413 SetNextEnumerationIndex(index + 1); |
| 15382 } | 15414 } |
| 15383 SetEntry(entry, k, value, details); | 15415 SetEntry(entry, k, value, details); |
| 15384 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || | 15416 ASSERT((Dictionary::KeyAt(entry)->IsNumber() || |
| 15385 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); | 15417 Dictionary::KeyAt(entry)->IsName())); |
| 15386 HashTable<Shape, Key>::ElementAdded(); | 15418 DerivedHashTable::ElementAdded(); |
| 15387 return this; | 15419 return this; |
| 15388 } | 15420 } |
| 15389 | 15421 |
| 15390 | 15422 |
| 15391 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15423 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 15392 // If the dictionary requires slow elements an element has already | 15424 // If the dictionary requires slow elements an element has already |
| 15393 // been added at a high index. | 15425 // been added at a high index. |
| 15394 if (requires_slow_elements()) return; | 15426 if (requires_slow_elements()) return; |
| 15395 // Check if this index is high enough that we should require slow | 15427 // Check if this index is high enough that we should require slow |
| 15396 // elements. | 15428 // elements. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15490 MaybeObject* maybe_object_key = | 15522 MaybeObject* maybe_object_key = |
| 15491 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); | 15523 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); |
| 15492 Object* object_key; | 15524 Object* object_key; |
| 15493 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 15525 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 15494 SetEntry(entry, object_key, value); | 15526 SetEntry(entry, object_key, value); |
| 15495 return this; | 15527 return this; |
| 15496 } | 15528 } |
| 15497 | 15529 |
| 15498 | 15530 |
| 15499 | 15531 |
| 15500 template<typename Shape, typename Key> | 15532 template<typename Derived, typename Shape, typename Key> |
| 15501 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 15533 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 15502 PropertyAttributes filter) { | 15534 PropertyAttributes filter) { |
| 15503 int capacity = HashTable<Shape, Key>::Capacity(); | 15535 int capacity = DerivedHashTable::Capacity(); |
| 15504 int result = 0; | 15536 int result = 0; |
| 15505 for (int i = 0; i < capacity; i++) { | 15537 for (int i = 0; i < capacity; i++) { |
| 15506 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15538 Object* k = DerivedHashTable::KeyAt(i); |
| 15507 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15539 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15508 PropertyDetails details = DetailsAt(i); | 15540 PropertyDetails details = DetailsAt(i); |
| 15509 if (details.IsDeleted()) continue; | 15541 if (details.IsDeleted()) continue; |
| 15510 PropertyAttributes attr = details.attributes(); | 15542 PropertyAttributes attr = details.attributes(); |
| 15511 if ((attr & filter) == 0) result++; | 15543 if ((attr & filter) == 0) result++; |
| 15512 } | 15544 } |
| 15513 } | 15545 } |
| 15514 return result; | 15546 return result; |
| 15515 } | 15547 } |
| 15516 | 15548 |
| 15517 | 15549 |
| 15518 template<typename Shape, typename Key> | 15550 template<typename Derived, typename Shape, typename Key> |
| 15519 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 15551 int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { |
| 15520 return NumberOfElementsFilterAttributes( | 15552 return NumberOfElementsFilterAttributes( |
| 15521 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15553 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
| 15522 } | 15554 } |
| 15523 | 15555 |
| 15524 | 15556 |
| 15525 template<typename Shape, typename Key> | 15557 template<typename Derived, typename Shape, typename Key> |
| 15526 void Dictionary<Shape, Key>::CopyKeysTo( | 15558 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15527 FixedArray* storage, | 15559 FixedArray* storage, |
| 15528 PropertyAttributes filter, | 15560 PropertyAttributes filter, |
| 15529 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15561 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15530 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15562 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15531 int capacity = HashTable<Shape, Key>::Capacity(); | 15563 int capacity = DerivedHashTable::Capacity(); |
| 15532 int index = 0; | 15564 int index = 0; |
| 15533 for (int i = 0; i < capacity; i++) { | 15565 for (int i = 0; i < capacity; i++) { |
| 15534 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15566 Object* k = DerivedHashTable::KeyAt(i); |
| 15535 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15567 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15536 PropertyDetails details = DetailsAt(i); | 15568 PropertyDetails details = DetailsAt(i); |
| 15537 if (details.IsDeleted()) continue; | 15569 if (details.IsDeleted()) continue; |
| 15538 PropertyAttributes attr = details.attributes(); | 15570 PropertyAttributes attr = details.attributes(); |
| 15539 if ((attr & filter) == 0) storage->set(index++, k); | 15571 if ((attr & filter) == 0) storage->set(index++, k); |
| 15540 } | 15572 } |
| 15541 } | 15573 } |
| 15542 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15574 if (sort_mode == Dictionary::SORTED) { |
| 15543 storage->SortPairs(storage, index); | 15575 storage->SortPairs(storage, index); |
| 15544 } | 15576 } |
| 15545 ASSERT(storage->length() >= index); | 15577 ASSERT(storage->length() >= index); |
| 15546 } | 15578 } |
| 15547 | 15579 |
| 15548 | 15580 |
| 15549 struct EnumIndexComparator { | 15581 struct EnumIndexComparator { |
| 15550 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15582 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
| 15551 bool operator() (Smi* a, Smi* b) { | 15583 bool operator() (Smi* a, Smi* b) { |
| 15552 PropertyDetails da(dict->DetailsAt(a->value())); | 15584 PropertyDetails da(dict->DetailsAt(a->value())); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 15574 EnumIndexComparator cmp(this); | 15606 EnumIndexComparator cmp(this); |
| 15575 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 15607 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 15576 std::sort(start, start + length, cmp); | 15608 std::sort(start, start + length, cmp); |
| 15577 for (int i = 0; i < length; i++) { | 15609 for (int i = 0; i < length; i++) { |
| 15578 int index = Smi::cast(storage->get(i))->value(); | 15610 int index = Smi::cast(storage->get(i))->value(); |
| 15579 storage->set(i, KeyAt(index)); | 15611 storage->set(i, KeyAt(index)); |
| 15580 } | 15612 } |
| 15581 } | 15613 } |
| 15582 | 15614 |
| 15583 | 15615 |
| 15584 template<typename Shape, typename Key> | 15616 template<typename Derived, typename Shape, typename Key> |
| 15585 void Dictionary<Shape, Key>::CopyKeysTo( | 15617 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15586 FixedArray* storage, | 15618 FixedArray* storage, |
| 15587 int index, | 15619 int index, |
| 15588 PropertyAttributes filter, | 15620 PropertyAttributes filter, |
| 15589 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15621 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15590 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15622 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15591 int capacity = HashTable<Shape, Key>::Capacity(); | 15623 int capacity = DerivedHashTable::Capacity(); |
| 15592 for (int i = 0; i < capacity; i++) { | 15624 for (int i = 0; i < capacity; i++) { |
| 15593 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15625 Object* k = DerivedHashTable::KeyAt(i); |
| 15594 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15626 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15595 PropertyDetails details = DetailsAt(i); | 15627 PropertyDetails details = DetailsAt(i); |
| 15596 if (details.IsDeleted()) continue; | 15628 if (details.IsDeleted()) continue; |
| 15597 PropertyAttributes attr = details.attributes(); | 15629 PropertyAttributes attr = details.attributes(); |
| 15598 if ((attr & filter) == 0) storage->set(index++, k); | 15630 if ((attr & filter) == 0) storage->set(index++, k); |
| 15599 } | 15631 } |
| 15600 } | 15632 } |
| 15601 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15633 if (sort_mode == Dictionary::SORTED) { |
| 15602 storage->SortPairs(storage, index); | 15634 storage->SortPairs(storage, index); |
| 15603 } | 15635 } |
| 15604 ASSERT(storage->length() >= index); | 15636 ASSERT(storage->length() >= index); |
| 15605 } | 15637 } |
| 15606 | 15638 |
| 15607 | 15639 |
| 15608 // Backwards lookup (slow). | 15640 // Backwards lookup (slow). |
| 15609 template<typename Shape, typename Key> | 15641 template<typename Derived, typename Shape, typename Key> |
| 15610 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 15642 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 15611 int capacity = HashTable<Shape, Key>::Capacity(); | 15643 int capacity = DerivedHashTable::Capacity(); |
| 15612 for (int i = 0; i < capacity; i++) { | 15644 for (int i = 0; i < capacity; i++) { |
| 15613 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15645 Object* k = DerivedHashTable::KeyAt(i); |
| 15614 if (Dictionary<Shape, Key>::IsKey(k)) { | 15646 if (Dictionary::IsKey(k)) { |
| 15615 Object* e = ValueAt(i); | 15647 Object* e = ValueAt(i); |
| 15616 if (e->IsPropertyCell()) { | 15648 if (e->IsPropertyCell()) { |
| 15617 e = PropertyCell::cast(e)->value(); | 15649 e = PropertyCell::cast(e)->value(); |
| 15618 } | 15650 } |
| 15619 if (e == value) return k; | 15651 if (e == value) return k; |
| 15620 } | 15652 } |
| 15621 } | 15653 } |
| 15622 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15654 Heap* heap = Dictionary::GetHeap(); |
| 15623 return heap->undefined_value(); | 15655 return heap->undefined_value(); |
| 15624 } | 15656 } |
| 15625 | 15657 |
| 15626 | 15658 |
| 15627 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15659 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
| 15628 Handle<ObjectHashTable> table, | 15660 Handle<ObjectHashTable> table, |
| 15629 int n, | 15661 int n, |
| 15630 Handle<Object> key, | 15662 Handle<Object> key, |
| 15631 PretenureFlag pretenure) { | 15663 PretenureFlag pretenure) { |
| 15632 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | 15664 Handle<HashTable<ObjectHashTable, |
| 15665 ObjectHashTableShape, |
| 15666 Object*> > table_base = table; |
| 15633 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15667 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| 15634 table_base->EnsureCapacity(n, *key, pretenure), | 15668 table_base->EnsureCapacity(n, *key, pretenure), |
| 15635 ObjectHashTable); | 15669 ObjectHashTable); |
| 15636 } | 15670 } |
| 15637 | 15671 |
| 15638 | 15672 |
| 15639 Handle<ObjectHashTable> ObjectHashTable::Shrink( | |
| 15640 Handle<ObjectHashTable> table, Handle<Object> key) { | |
| 15641 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | |
| 15642 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | |
| 15643 table_base->Shrink(*key), | |
| 15644 ObjectHashTable); | |
| 15645 } | |
| 15646 | |
| 15647 | |
| 15648 Object* ObjectHashTable::Lookup(Object* key) { | 15673 Object* ObjectHashTable::Lookup(Object* key) { |
| 15649 ASSERT(IsKey(key)); | 15674 ASSERT(IsKey(key)); |
| 15650 | 15675 |
| 15651 // If the object does not have an identity hash, it was never used as a key. | 15676 // If the object does not have an identity hash, it was never used as a key. |
| 15652 Object* hash = key->GetHash(); | 15677 Object* hash = key->GetHash(); |
| 15653 if (hash->IsUndefined()) { | 15678 if (hash->IsUndefined()) { |
| 15654 return GetHeap()->the_hole_value(); | 15679 return GetHeap()->the_hole_value(); |
| 15655 } | 15680 } |
| 15656 int entry = FindEntry(key); | 15681 int entry = FindEntry(key); |
| 15657 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15682 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16517 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16542 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16518 static const char* error_messages_[] = { | 16543 static const char* error_messages_[] = { |
| 16519 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16544 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16520 }; | 16545 }; |
| 16521 #undef ERROR_MESSAGES_TEXTS | 16546 #undef ERROR_MESSAGES_TEXTS |
| 16522 return error_messages_[reason]; | 16547 return error_messages_[reason]; |
| 16523 } | 16548 } |
| 16524 | 16549 |
| 16525 | 16550 |
| 16526 } } // namespace v8::internal | 16551 } } // namespace v8::internal |
| OLD | NEW |