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 |