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