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 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 684 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
685 PropertyCell::SetValueInferType(cell, value); | 685 PropertyCell::SetValueInferType(cell, value); |
686 // Please note we have to update the property details. | 686 // Please note we have to update the property details. |
687 property_dictionary->DetailsAtPut(entry, details); | 687 property_dictionary->DetailsAtPut(entry, details); |
688 } else { | 688 } else { |
689 property_dictionary->SetEntry(entry, *name, *value, details); | 689 property_dictionary->SetEntry(entry, *name, *value, details); |
690 } | 690 } |
691 } | 691 } |
692 | 692 |
693 | 693 |
| 694 // TODO(mstarzinger): Temporary wrapper until target is handlified. |
| 695 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, |
| 696 Handle<Name> name) { |
| 697 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); |
| 698 } |
| 699 |
| 700 |
694 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 701 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
695 Handle<Name> name, | 702 Handle<Name> name, |
696 DeleteMode mode) { | 703 DeleteMode mode) { |
697 ASSERT(!object->HasFastProperties()); | 704 ASSERT(!object->HasFastProperties()); |
698 Isolate* isolate = object->GetIsolate(); | 705 Isolate* isolate = object->GetIsolate(); |
699 Handle<NameDictionary> dictionary(object->property_dictionary()); | 706 Handle<NameDictionary> dictionary(object->property_dictionary()); |
700 int entry = dictionary->FindEntry(*name); | 707 int entry = dictionary->FindEntry(*name); |
701 if (entry != NameDictionary::kNotFound) { | 708 if (entry != NameDictionary::kNotFound) { |
702 // If we have a global object set the cell to the hole. | 709 // If we have a global object set the cell to the hole. |
703 if (object->IsGlobalObject()) { | 710 if (object->IsGlobalObject()) { |
704 PropertyDetails details = dictionary->DetailsAt(entry); | 711 PropertyDetails details = dictionary->DetailsAt(entry); |
705 if (details.IsDontDelete()) { | 712 if (details.IsDontDelete()) { |
706 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 713 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
707 // When forced to delete global properties, we have to make a | 714 // When forced to delete global properties, we have to make a |
708 // map change to invalidate any ICs that think they can load | 715 // map change to invalidate any ICs that think they can load |
709 // from the DontDelete cell without checking if it contains | 716 // from the DontDelete cell without checking if it contains |
710 // the hole value. | 717 // the hole value. |
711 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 718 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
712 ASSERT(new_map->is_dictionary_map()); | 719 ASSERT(new_map->is_dictionary_map()); |
713 object->set_map(*new_map); | 720 object->set_map(*new_map); |
714 } | 721 } |
715 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 722 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
716 Handle<Object> value = isolate->factory()->the_hole_value(); | 723 Handle<Object> value = isolate->factory()->the_hole_value(); |
717 PropertyCell::SetValueInferType(cell, value); | 724 PropertyCell::SetValueInferType(cell, value); |
718 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 725 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
719 } else { | 726 } else { |
720 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); | 727 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
721 if (*deleted == isolate->heap()->true_value()) { | 728 if (*deleted == isolate->heap()->true_value()) { |
722 Handle<NameDictionary> new_properties = | 729 Handle<NameDictionary> new_properties = |
723 NameDictionary::Shrink(dictionary, *name); | 730 NameDictionaryShrink(dictionary, name); |
724 object->set_properties(*new_properties); | 731 object->set_properties(*new_properties); |
725 } | 732 } |
726 return deleted; | 733 return deleted; |
727 } | 734 } |
728 } | 735 } |
729 return isolate->factory()->true_value(); | 736 return isolate->factory()->true_value(); |
730 } | 737 } |
731 | 738 |
732 | 739 |
733 bool JSObject::IsDirty() { | 740 bool JSObject::IsDirty() { |
(...skipping 12423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13157 } | 13164 } |
13158 } | 13165 } |
13159 | 13166 |
13160 | 13167 |
13161 // Certain compilers request function template instantiation when they | 13168 // Certain compilers request function template instantiation when they |
13162 // see the definition of the other template functions in the | 13169 // see the definition of the other template functions in the |
13163 // class. This requires us to have the template functions put | 13170 // class. This requires us to have the template functions put |
13164 // together, so even though this function belongs in objects-debug.cc, | 13171 // together, so even though this function belongs in objects-debug.cc, |
13165 // we keep it here instead to satisfy certain compilers. | 13172 // we keep it here instead to satisfy certain compilers. |
13166 #ifdef OBJECT_PRINT | 13173 #ifdef OBJECT_PRINT |
13167 template<typename Derived, typename Shape, typename Key> | 13174 template<typename Shape, typename Key> |
13168 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { | 13175 void Dictionary<Shape, Key>::Print(FILE* out) { |
13169 int capacity = DerivedHashTable::Capacity(); | 13176 int capacity = HashTable<Shape, Key>::Capacity(); |
13170 for (int i = 0; i < capacity; i++) { | 13177 for (int i = 0; i < capacity; i++) { |
13171 Object* k = DerivedHashTable::KeyAt(i); | 13178 Object* k = HashTable<Shape, Key>::KeyAt(i); |
13172 if (DerivedHashTable::IsKey(k)) { | 13179 if (HashTable<Shape, Key>::IsKey(k)) { |
13173 PrintF(out, " "); | 13180 PrintF(out, " "); |
13174 if (k->IsString()) { | 13181 if (k->IsString()) { |
13175 String::cast(k)->StringPrint(out); | 13182 String::cast(k)->StringPrint(out); |
13176 } else { | 13183 } else { |
13177 k->ShortPrint(out); | 13184 k->ShortPrint(out); |
13178 } | 13185 } |
13179 PrintF(out, ": "); | 13186 PrintF(out, ": "); |
13180 ValueAt(i)->ShortPrint(out); | 13187 ValueAt(i)->ShortPrint(out); |
13181 PrintF(out, "\n"); | 13188 PrintF(out, "\n"); |
13182 } | 13189 } |
13183 } | 13190 } |
13184 } | 13191 } |
13185 #endif | 13192 #endif |
13186 | 13193 |
13187 | 13194 |
13188 template<typename Derived, typename Shape, typename Key> | 13195 template<typename Shape, typename Key> |
13189 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13196 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { |
13190 int pos = 0; | 13197 int pos = 0; |
13191 int capacity = DerivedHashTable::Capacity(); | 13198 int capacity = HashTable<Shape, Key>::Capacity(); |
13192 DisallowHeapAllocation no_gc; | 13199 DisallowHeapAllocation no_gc; |
13193 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13200 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
13194 for (int i = 0; i < capacity; i++) { | 13201 for (int i = 0; i < capacity; i++) { |
13195 Object* k = Dictionary::KeyAt(i); | 13202 Object* k = Dictionary<Shape, Key>::KeyAt(i); |
13196 if (Dictionary::IsKey(k)) { | 13203 if (Dictionary<Shape, Key>::IsKey(k)) { |
13197 elements->set(pos++, ValueAt(i), mode); | 13204 elements->set(pos++, ValueAt(i), mode); |
13198 } | 13205 } |
13199 } | 13206 } |
13200 ASSERT(pos == elements->length()); | 13207 ASSERT(pos == elements->length()); |
13201 } | 13208 } |
13202 | 13209 |
13203 | 13210 |
13204 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13211 InterceptorInfo* JSObject::GetNamedInterceptor() { |
13205 ASSERT(map()->has_named_interceptor()); | 13212 ASSERT(map()->has_named_interceptor()); |
13206 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13213 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13890 } | 13897 } |
13891 | 13898 |
13892 static uint32_t StringHash(Object* obj) { | 13899 static uint32_t StringHash(Object* obj) { |
13893 return String::cast(obj)->Hash(); | 13900 return String::cast(obj)->Hash(); |
13894 } | 13901 } |
13895 | 13902 |
13896 String* string_; | 13903 String* string_; |
13897 }; | 13904 }; |
13898 | 13905 |
13899 | 13906 |
13900 template<typename Derived, typename Shape, typename Key> | 13907 template<typename Shape, typename Key> |
13901 void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) { | 13908 void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
13902 IteratePointers(v, 0, kElementsStartOffset); | 13909 IteratePointers(v, 0, kElementsStartOffset); |
13903 } | 13910 } |
13904 | 13911 |
13905 | 13912 |
13906 template<typename Derived, typename Shape, typename Key> | 13913 template<typename Shape, typename Key> |
13907 void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) { | 13914 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { |
13908 IteratePointers(v, | 13915 IteratePointers(v, |
13909 kElementsStartOffset, | 13916 kElementsStartOffset, |
13910 kHeaderSize + length() * kPointerSize); | 13917 kHeaderSize + length() * kPointerSize); |
13911 } | 13918 } |
13912 | 13919 |
13913 | 13920 |
13914 template<typename Derived, typename Shape, typename Key> | 13921 template<typename Shape, typename Key> |
13915 MaybeObject* HashTable<Derived, Shape, Key>::Allocate( | 13922 MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap, |
13916 Heap* heap, | 13923 int at_least_space_for, |
13917 int at_least_space_for, | 13924 MinimumCapacity capacity_option, |
13918 MinimumCapacity capacity_option, | 13925 PretenureFlag pretenure) { |
13919 PretenureFlag pretenure) { | |
13920 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 13926 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); |
13921 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 13927 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
13922 ? at_least_space_for | 13928 ? at_least_space_for |
13923 : ComputeCapacity(at_least_space_for); | 13929 : ComputeCapacity(at_least_space_for); |
13924 if (capacity > HashTable::kMaxCapacity) { | 13930 if (capacity > HashTable::kMaxCapacity) { |
13925 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 13931 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
13926 } | 13932 } |
13927 | 13933 |
13928 Object* obj; | 13934 Object* obj; |
13929 { MaybeObject* maybe_obj = | 13935 { MaybeObject* maybe_obj = |
13930 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); | 13936 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); |
13931 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13937 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
13932 } | 13938 } |
13933 HashTable::cast(obj)->SetNumberOfElements(0); | 13939 HashTable::cast(obj)->SetNumberOfElements(0); |
13934 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 13940 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
13935 HashTable::cast(obj)->SetCapacity(capacity); | 13941 HashTable::cast(obj)->SetCapacity(capacity); |
13936 return obj; | 13942 return obj; |
13937 } | 13943 } |
13938 | 13944 |
13939 | 13945 |
13940 template<typename Derived, typename Shape, typename Key> | |
13941 Handle<Derived> HashTable<Derived, Shape, Key>::New( | |
13942 Isolate* isolate, | |
13943 int at_least_space_for, | |
13944 MinimumCapacity capacity_option, | |
13945 PretenureFlag pretenure) { | |
13946 CALL_HEAP_FUNCTION( | |
13947 isolate, | |
13948 Allocate(isolate->heap(), at_least_space_for, capacity_option, pretenure), | |
13949 Derived); | |
13950 } | |
13951 | |
13952 | |
13953 // Find entry for key otherwise return kNotFound. | 13946 // Find entry for key otherwise return kNotFound. |
13954 int NameDictionary::FindEntry(Name* key) { | 13947 int NameDictionary::FindEntry(Name* key) { |
13955 if (!key->IsUniqueName()) { | 13948 if (!key->IsUniqueName()) { |
13956 return DerivedHashTable::FindEntry(key); | 13949 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); |
13957 } | 13950 } |
13958 | 13951 |
13959 // Optimized for unique names. Knowledge of the key type allows: | 13952 // Optimized for unique names. Knowledge of the key type allows: |
13960 // 1. Move the check if the key is unique out of the loop. | 13953 // 1. Move the check if the key is unique out of the loop. |
13961 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 13954 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
13962 // 3. Detect a case when a dictionary key is not unique but the key is. | 13955 // 3. Detect a case when a dictionary key is not unique but the key is. |
13963 // In case of positive result the dictionary key may be replaced by the | 13956 // In case of positive result the dictionary key may be replaced by the |
13964 // internalized string with minimal performance penalty. It gives a chance | 13957 // internalized string with minimal performance penalty. It gives a chance |
13965 // to perform further lookups in code stubs (and significant performance | 13958 // to perform further lookups in code stubs (and significant performance |
13966 // boost a certain style of code). | 13959 // boost a certain style of code). |
(...skipping 16 matching lines...) Expand all Loading... |
13983 set(index, key); | 13976 set(index, key); |
13984 return entry; | 13977 return entry; |
13985 } | 13978 } |
13986 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); | 13979 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
13987 entry = NextProbe(entry, count++, capacity); | 13980 entry = NextProbe(entry, count++, capacity); |
13988 } | 13981 } |
13989 return kNotFound; | 13982 return kNotFound; |
13990 } | 13983 } |
13991 | 13984 |
13992 | 13985 |
13993 template<typename Derived, typename Shape, typename Key> | 13986 template<typename Shape, typename Key> |
13994 void HashTable<Derived, Shape, Key>::Rehash(Derived* new_table, Key key) { | 13987 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { |
13995 ASSERT(NumberOfElements() < new_table->Capacity()); | 13988 ASSERT(NumberOfElements() < new_table->Capacity()); |
13996 | 13989 |
13997 DisallowHeapAllocation no_gc; | 13990 DisallowHeapAllocation no_gc; |
13998 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 13991 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
13999 | 13992 |
14000 // Copy prefix to new array. | 13993 // Copy prefix to new array. |
14001 for (int i = kPrefixStartIndex; | 13994 for (int i = kPrefixStartIndex; |
14002 i < kPrefixStartIndex + Shape::kPrefixSize; | 13995 i < kPrefixStartIndex + Shape::kPrefixSize; |
14003 i++) { | 13996 i++) { |
14004 new_table->set(i, get(i), mode); | 13997 new_table->set(i, get(i), mode); |
14005 } | 13998 } |
14006 | 13999 |
14007 // Rehash the elements. | 14000 // Rehash the elements. |
14008 int capacity = Capacity(); | 14001 int capacity = Capacity(); |
14009 for (int i = 0; i < capacity; i++) { | 14002 for (int i = 0; i < capacity; i++) { |
14010 uint32_t from_index = EntryToIndex(i); | 14003 uint32_t from_index = EntryToIndex(i); |
14011 Object* k = get(from_index); | 14004 Object* k = get(from_index); |
14012 if (IsKey(k)) { | 14005 if (IsKey(k)) { |
14013 uint32_t hash = HashTable::HashForObject(key, k); | 14006 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); |
14014 uint32_t insertion_index = | 14007 uint32_t insertion_index = |
14015 EntryToIndex(new_table->FindInsertionEntry(hash)); | 14008 EntryToIndex(new_table->FindInsertionEntry(hash)); |
14016 for (int j = 0; j < Shape::kEntrySize; j++) { | 14009 for (int j = 0; j < Shape::kEntrySize; j++) { |
14017 new_table->set(insertion_index + j, get(from_index + j), mode); | 14010 new_table->set(insertion_index + j, get(from_index + j), mode); |
14018 } | 14011 } |
14019 } | 14012 } |
14020 } | 14013 } |
14021 new_table->SetNumberOfElements(NumberOfElements()); | 14014 new_table->SetNumberOfElements(NumberOfElements()); |
14022 new_table->SetNumberOfDeletedElements(0); | 14015 new_table->SetNumberOfDeletedElements(0); |
| 14016 return new_table; |
14023 } | 14017 } |
14024 | 14018 |
14025 | 14019 |
14026 template<typename Derived, typename Shape, typename Key> | 14020 template<typename Shape, typename Key> |
14027 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( | 14021 uint32_t HashTable<Shape, Key>::EntryForProbe(Key key, |
14028 Key key, | 14022 Object* k, |
14029 Object* k, | 14023 int probe, |
14030 int probe, | 14024 uint32_t expected) { |
14031 uint32_t expected) { | 14025 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); |
14032 uint32_t hash = HashTable::HashForObject(key, k); | |
14033 uint32_t capacity = Capacity(); | 14026 uint32_t capacity = Capacity(); |
14034 uint32_t entry = FirstProbe(hash, capacity); | 14027 uint32_t entry = FirstProbe(hash, capacity); |
14035 for (int i = 1; i < probe; i++) { | 14028 for (int i = 1; i < probe; i++) { |
14036 if (entry == expected) return expected; | 14029 if (entry == expected) return expected; |
14037 entry = NextProbe(entry, i, capacity); | 14030 entry = NextProbe(entry, i, capacity); |
14038 } | 14031 } |
14039 return entry; | 14032 return entry; |
14040 } | 14033 } |
14041 | 14034 |
14042 | 14035 |
14043 template<typename Derived, typename Shape, typename Key> | 14036 template<typename Shape, typename Key> |
14044 void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1, | 14037 void HashTable<Shape, Key>::Swap(uint32_t entry1, |
14045 uint32_t entry2, | 14038 uint32_t entry2, |
14046 WriteBarrierMode mode) { | 14039 WriteBarrierMode mode) { |
14047 int index1 = EntryToIndex(entry1); | 14040 int index1 = EntryToIndex(entry1); |
14048 int index2 = EntryToIndex(entry2); | 14041 int index2 = EntryToIndex(entry2); |
14049 Object* temp[Shape::kEntrySize]; | 14042 Object* temp[Shape::kEntrySize]; |
14050 for (int j = 0; j < Shape::kEntrySize; j++) { | 14043 for (int j = 0; j < Shape::kEntrySize; j++) { |
14051 temp[j] = get(index1 + j); | 14044 temp[j] = get(index1 + j); |
14052 } | 14045 } |
14053 for (int j = 0; j < Shape::kEntrySize; j++) { | 14046 for (int j = 0; j < Shape::kEntrySize; j++) { |
14054 set(index1 + j, get(index2 + j), mode); | 14047 set(index1 + j, get(index2 + j), mode); |
14055 } | 14048 } |
14056 for (int j = 0; j < Shape::kEntrySize; j++) { | 14049 for (int j = 0; j < Shape::kEntrySize; j++) { |
14057 set(index2 + j, temp[j], mode); | 14050 set(index2 + j, temp[j], mode); |
14058 } | 14051 } |
14059 } | 14052 } |
14060 | 14053 |
14061 | 14054 |
14062 template<typename Derived, typename Shape, typename Key> | 14055 template<typename Shape, typename Key> |
14063 void HashTable<Derived, Shape, Key>::Rehash(Key key) { | 14056 void HashTable<Shape, Key>::Rehash(Key key) { |
14064 DisallowHeapAllocation no_gc; | 14057 DisallowHeapAllocation no_gc; |
14065 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 14058 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
14066 uint32_t capacity = Capacity(); | 14059 uint32_t capacity = Capacity(); |
14067 bool done = false; | 14060 bool done = false; |
14068 for (int probe = 1; !done; probe++) { | 14061 for (int probe = 1; !done; probe++) { |
14069 // All elements at entries given by one of the first _probe_ probes | 14062 // All elements at entries given by one of the first _probe_ probes |
14070 // are placed correctly. Other elements might need to be moved. | 14063 // are placed correctly. Other elements might need to be moved. |
14071 done = true; | 14064 done = true; |
14072 for (uint32_t current = 0; current < capacity; current++) { | 14065 for (uint32_t current = 0; current < capacity; current++) { |
14073 Object* current_key = get(EntryToIndex(current)); | 14066 Object* current_key = get(EntryToIndex(current)); |
(...skipping 11 matching lines...) Expand all Loading... |
14085 // The place for the current element is occupied. Leave the element | 14078 // The place for the current element is occupied. Leave the element |
14086 // for the next probe. | 14079 // for the next probe. |
14087 done = false; | 14080 done = false; |
14088 } | 14081 } |
14089 } | 14082 } |
14090 } | 14083 } |
14091 } | 14084 } |
14092 } | 14085 } |
14093 | 14086 |
14094 | 14087 |
14095 template<typename Derived, typename Shape, typename Key> | 14088 template<typename Shape, typename Key> |
14096 MaybeObject* HashTable<Derived, Shape, Key>::EnsureCapacity( | 14089 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, |
14097 int n, | 14090 Key key, |
14098 Key key, | 14091 PretenureFlag pretenure) { |
14099 PretenureFlag pretenure) { | |
14100 int capacity = Capacity(); | 14092 int capacity = Capacity(); |
14101 int nof = NumberOfElements() + n; | 14093 int nof = NumberOfElements() + n; |
14102 int nod = NumberOfDeletedElements(); | 14094 int nod = NumberOfDeletedElements(); |
14103 // Return if: | 14095 // Return if: |
14104 // 50% is still free after adding n elements and | 14096 // 50% is still free after adding n elements and |
14105 // at most 50% of the free elements are deleted elements. | 14097 // at most 50% of the free elements are deleted elements. |
14106 if (nod <= (capacity - nof) >> 1) { | 14098 if (nod <= (capacity - nof) >> 1) { |
14107 int needed_free = nof >> 1; | 14099 int needed_free = nof >> 1; |
14108 if (nof + needed_free <= capacity) return this; | 14100 if (nof + needed_free <= capacity) return this; |
14109 } | 14101 } |
14110 | 14102 |
14111 const int kMinCapacityForPretenure = 256; | 14103 const int kMinCapacityForPretenure = 256; |
14112 bool should_pretenure = pretenure == TENURED || | 14104 bool should_pretenure = pretenure == TENURED || |
14113 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); | 14105 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
14114 Object* obj; | 14106 Object* obj; |
14115 { MaybeObject* maybe_obj = | 14107 { MaybeObject* maybe_obj = |
14116 Allocate(GetHeap(), | 14108 Allocate(GetHeap(), |
14117 nof * 2, | 14109 nof * 2, |
14118 USE_DEFAULT_MINIMUM_CAPACITY, | 14110 USE_DEFAULT_MINIMUM_CAPACITY, |
14119 should_pretenure ? TENURED : NOT_TENURED); | 14111 should_pretenure ? TENURED : NOT_TENURED); |
14120 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 14112 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
14121 } | 14113 } |
14122 | 14114 |
14123 Rehash(Derived::cast(obj), key); | 14115 return Rehash(HashTable::cast(obj), key); |
14124 return Derived::cast(obj); | |
14125 } | 14116 } |
14126 | 14117 |
14127 | 14118 |
14128 template<typename Derived, typename Shape, typename Key> | 14119 template<typename Shape, typename Key> |
14129 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, | 14120 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { |
14130 Key key) { | 14121 int capacity = Capacity(); |
14131 int capacity = table->Capacity(); | 14122 int nof = NumberOfElements(); |
14132 int nof = table->NumberOfElements(); | |
14133 | 14123 |
14134 // Shrink to fit the number of elements if only a quarter of the | 14124 // Shrink to fit the number of elements if only a quarter of the |
14135 // capacity is filled with elements. | 14125 // capacity is filled with elements. |
14136 if (nof > (capacity >> 2)) return table; | 14126 if (nof > (capacity >> 2)) return this; |
14137 // Allocate a new dictionary with room for at least the current | 14127 // Allocate a new dictionary with room for at least the current |
14138 // number of elements. The allocation method will make sure that | 14128 // number of elements. The allocation method will make sure that |
14139 // there is extra room in the dictionary for additions. Don't go | 14129 // there is extra room in the dictionary for additions. Don't go |
14140 // lower than room for 16 elements. | 14130 // lower than room for 16 elements. |
14141 int at_least_room_for = nof; | 14131 int at_least_room_for = nof; |
14142 if (at_least_room_for < 16) return table; | 14132 if (at_least_room_for < 16) return this; |
14143 | 14133 |
14144 Isolate* isolate = table->GetIsolate(); | |
14145 const int kMinCapacityForPretenure = 256; | 14134 const int kMinCapacityForPretenure = 256; |
14146 bool pretenure = | 14135 bool pretenure = |
14147 (at_least_room_for > kMinCapacityForPretenure) && | 14136 (at_least_room_for > kMinCapacityForPretenure) && |
14148 !isolate->heap()->InNewSpace(*table); | 14137 !GetHeap()->InNewSpace(this); |
14149 Handle<Derived> new_table = New( | 14138 Object* obj; |
14150 isolate, | 14139 { MaybeObject* maybe_obj = |
14151 at_least_room_for, | 14140 Allocate(GetHeap(), |
14152 USE_DEFAULT_MINIMUM_CAPACITY, | 14141 at_least_room_for, |
14153 pretenure ? TENURED : NOT_TENURED); | 14142 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14143 pretenure ? TENURED : NOT_TENURED); |
| 14144 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 14145 } |
14154 | 14146 |
14155 table->Rehash(*new_table, key); | 14147 return Rehash(HashTable::cast(obj), key); |
14156 return new_table; | |
14157 } | 14148 } |
14158 | 14149 |
14159 | 14150 |
14160 template<typename Derived, typename Shape, typename Key> | 14151 template<typename Shape, typename Key> |
14161 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { | 14152 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { |
14162 uint32_t capacity = Capacity(); | 14153 uint32_t capacity = Capacity(); |
14163 uint32_t entry = FirstProbe(hash, capacity); | 14154 uint32_t entry = FirstProbe(hash, capacity); |
14164 uint32_t count = 1; | 14155 uint32_t count = 1; |
14165 // EnsureCapacity will guarantee the hash table is never full. | 14156 // EnsureCapacity will guarantee the hash table is never full. |
14166 while (true) { | 14157 while (true) { |
14167 Object* element = KeyAt(entry); | 14158 Object* element = KeyAt(entry); |
14168 if (element->IsUndefined() || element->IsTheHole()) break; | 14159 if (element->IsUndefined() || element->IsTheHole()) break; |
14169 entry = NextProbe(entry, count++, capacity); | 14160 entry = NextProbe(entry, count++, capacity); |
14170 } | 14161 } |
14171 return entry; | 14162 return entry; |
14172 } | 14163 } |
14173 | 14164 |
14174 | 14165 |
14175 // Force instantiation of template instances class. | 14166 // Force instantiation of template instances class. |
14176 // Please note this list is compiler dependent. | 14167 // Please note this list is compiler dependent. |
14177 | 14168 |
14178 template class HashTable<StringTable, StringTableShape, HashTableKey*>; | 14169 template class HashTable<StringTableShape, HashTableKey*>; |
14179 | 14170 |
14180 template class HashTable<CompilationCacheTable, | 14171 template class HashTable<CompilationCacheShape, HashTableKey*>; |
14181 CompilationCacheShape, | |
14182 HashTableKey*>; | |
14183 | 14172 |
14184 template class HashTable<MapCache, MapCacheShape, HashTableKey*>; | 14173 template class HashTable<MapCacheShape, HashTableKey*>; |
14185 | 14174 |
14186 template class HashTable<ObjectHashTable, ObjectHashTableShape, Object*>; | 14175 template class HashTable<ObjectHashTableShape, Object*>; |
14187 | 14176 |
14188 template class HashTable<WeakHashTable, WeakHashTableShape<2>, Object*>; | 14177 template class HashTable<WeakHashTableShape<2>, Object*>; |
14189 | 14178 |
14190 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; | 14179 template class Dictionary<NameDictionaryShape, Name*>; |
14191 | 14180 |
14192 template class Dictionary<SeededNumberDictionary, | 14181 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
14193 SeededNumberDictionaryShape, | |
14194 uint32_t>; | |
14195 | 14182 |
14196 template class Dictionary<UnseededNumberDictionary, | 14183 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; |
14197 UnseededNumberDictionaryShape, | |
14198 uint32_t>; | |
14199 | 14184 |
14200 template MaybeObject* | 14185 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14201 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | |
14202 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14186 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
14203 | 14187 |
14204 template MaybeObject* | 14188 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
14205 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | |
14206 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14189 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
14207 | 14190 |
14208 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14191 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: |
14209 Allocate(Heap* heap, int n, PretenureFlag pretenure); | 14192 Allocate(Heap* heap, int n, PretenureFlag pretenure); |
14210 | 14193 |
14211 template MaybeObject* | 14194 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( |
14212 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14195 uint32_t, Object*); |
| 14196 |
| 14197 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
14213 AtPut(uint32_t, Object*); | 14198 AtPut(uint32_t, Object*); |
14214 | 14199 |
14215 template MaybeObject* | 14200 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14216 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | |
14217 AtPut(uint32_t, Object*); | |
14218 | |
14219 template Object* | |
14220 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | |
14221 SlowReverseLookup(Object* value); | 14201 SlowReverseLookup(Object* value); |
14222 | 14202 |
14223 template Object* | 14203 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
14224 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | |
14225 SlowReverseLookup(Object* value); | 14204 SlowReverseLookup(Object* value); |
14226 | 14205 |
14227 template Object* | 14206 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( |
14228 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SlowReverseLookup( | |
14229 Object*); | 14207 Object*); |
14230 | 14208 |
14231 template void | 14209 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( |
14232 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14210 FixedArray*, |
14233 CopyKeysTo( | 14211 PropertyAttributes, |
14234 FixedArray*, | 14212 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); |
14235 PropertyAttributes, | |
14236 Dictionary<SeededNumberDictionary, | |
14237 SeededNumberDictionaryShape, | |
14238 uint32_t>::SortMode); | |
14239 | 14213 |
14240 template Object* | 14214 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( |
14241 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( | |
14242 int, JSObject::DeleteMode); | 14215 int, JSObject::DeleteMode); |
14243 | 14216 |
14244 template Handle<Object> | 14217 template Handle<Object> Dictionary<NameDictionaryShape, Name*>::DeleteProperty( |
14245 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( | 14218 Handle<Dictionary<NameDictionaryShape, Name*> >, |
14246 Handle<Dictionary<NameDictionary, NameDictionaryShape, Name*> >, | |
14247 int, | 14219 int, |
14248 JSObject::DeleteMode); | 14220 JSObject::DeleteMode); |
14249 | 14221 |
14250 template Object* | 14222 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14251 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | |
14252 DeleteProperty(int, JSObject::DeleteMode); | 14223 DeleteProperty(int, JSObject::DeleteMode); |
14253 | 14224 |
14254 template Handle<Object> | 14225 template Handle<Object> |
14255 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14226 Dictionary<SeededNumberDictionaryShape, uint32_t>::DeleteProperty( |
14256 DeleteProperty( | 14227 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, |
14257 Handle<Dictionary<SeededNumberDictionary, | 14228 int, |
14258 SeededNumberDictionaryShape, | 14229 JSObject::DeleteMode); |
14259 uint32_t> >, | |
14260 int, | |
14261 JSObject::DeleteMode); | |
14262 | 14230 |
14263 template Handle<NameDictionary> | 14231 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); |
14264 HashTable<NameDictionary, NameDictionaryShape, Name*>:: | |
14265 Shrink(Handle<NameDictionary>, Name* n); | |
14266 | 14232 |
14267 template Handle<SeededNumberDictionary> | 14233 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( |
14268 HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14234 uint32_t); |
14269 Shrink(Handle<SeededNumberDictionary>, uint32_t); | 14235 template Handle<FixedArray> |
| 14236 Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( |
| 14237 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, |
| 14238 uint32_t); |
14270 | 14239 |
14271 template void Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14240 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( |
14272 CopyKeysTo( | 14241 FixedArray*, |
14273 FixedArray*, | 14242 int, |
14274 int, | 14243 PropertyAttributes, |
14275 PropertyAttributes, | 14244 Dictionary<NameDictionaryShape, Name*>::SortMode); |
14276 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SortMode); | |
14277 | 14245 |
14278 template int | 14246 template int |
14279 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14247 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( |
14280 NumberOfElementsFilterAttributes(PropertyAttributes); | 14248 PropertyAttributes); |
14281 | 14249 |
14282 template MaybeObject* | 14250 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( |
14283 Dictionary<NameDictionary, NameDictionaryShape, Name*>::Add( | |
14284 Name*, Object*, PropertyDetails); | 14251 Name*, Object*, PropertyDetails); |
14285 | 14252 |
14286 template MaybeObject* | 14253 template MaybeObject* |
14287 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14254 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); |
14288 GenerateNewEnumerationIndices(); | |
14289 | 14255 |
14290 template int | 14256 template int |
14291 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14257 Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14292 NumberOfElementsFilterAttributes(PropertyAttributes); | 14258 NumberOfElementsFilterAttributes(PropertyAttributes); |
14293 | 14259 |
14294 template MaybeObject* | 14260 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( |
14295 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add( | |
14296 uint32_t, Object*, PropertyDetails); | 14261 uint32_t, Object*, PropertyDetails); |
14297 | 14262 |
14298 template MaybeObject* | 14263 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( |
14299 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | 14264 uint32_t, Object*, PropertyDetails); |
14300 Add(uint32_t, Object*, PropertyDetails); | |
14301 | 14265 |
14302 template MaybeObject* | 14266 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14303 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | |
14304 EnsureCapacity(int, uint32_t); | 14267 EnsureCapacity(int, uint32_t); |
14305 | 14268 |
14306 template MaybeObject* | 14269 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
14307 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | |
14308 EnsureCapacity(int, uint32_t); | 14270 EnsureCapacity(int, uint32_t); |
14309 | 14271 |
14310 template MaybeObject* | 14272 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: |
14311 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | |
14312 EnsureCapacity(int, Name*); | 14273 EnsureCapacity(int, Name*); |
14313 | 14274 |
14314 template MaybeObject* | 14275 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
14315 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | |
14316 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14276 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
14317 | 14277 |
14318 template MaybeObject* | 14278 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
14319 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | |
14320 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14279 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
14321 | 14280 |
14322 template MaybeObject* | 14281 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( |
14323 Dictionary<NameDictionary, NameDictionaryShape, Name*>::AddEntry( | |
14324 Name*, Object*, PropertyDetails, uint32_t); | 14282 Name*, Object*, PropertyDetails, uint32_t); |
14325 | 14283 |
14326 template | 14284 template |
14327 int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14285 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); |
14328 NumberOfEnumElements(); | |
14329 | 14286 |
14330 template | 14287 template |
14331 int Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14288 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); |
14332 NumberOfEnumElements(); | |
14333 | 14289 |
14334 template | 14290 template |
14335 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14291 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
14336 FindEntry(uint32_t); | |
14337 | 14292 |
14338 | 14293 |
14339 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14294 Handle<Object> JSObject::PrepareSlowElementsForSort( |
14340 Handle<JSObject> object, uint32_t limit) { | 14295 Handle<JSObject> object, uint32_t limit) { |
14341 CALL_HEAP_FUNCTION(object->GetIsolate(), | 14296 CALL_HEAP_FUNCTION(object->GetIsolate(), |
14342 object->PrepareSlowElementsForSort(limit), | 14297 object->PrepareSlowElementsForSort(limit), |
14343 Object); | 14298 Object); |
14344 } | 14299 } |
14345 | 14300 |
14346 | 14301 |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15172 | 15127 |
15173 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15128 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
15174 int entry = cache->FindInsertionEntry(key.Hash()); | 15129 int entry = cache->FindInsertionEntry(key.Hash()); |
15175 cache->set(EntryToIndex(entry), array); | 15130 cache->set(EntryToIndex(entry), array); |
15176 cache->set(EntryToIndex(entry) + 1, value); | 15131 cache->set(EntryToIndex(entry) + 1, value); |
15177 cache->ElementAdded(); | 15132 cache->ElementAdded(); |
15178 return cache; | 15133 return cache; |
15179 } | 15134 } |
15180 | 15135 |
15181 | 15136 |
15182 template<typename Derived, typename Shape, typename Key> | 15137 template<typename Shape, typename Key> |
15183 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( | 15138 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, |
15184 Heap* heap, | 15139 int at_least_space_for, |
15185 int at_least_space_for, | 15140 PretenureFlag pretenure) { |
15186 PretenureFlag pretenure) { | |
15187 Object* obj; | 15141 Object* obj; |
15188 { MaybeObject* maybe_obj = | 15142 { MaybeObject* maybe_obj = |
15189 DerivedHashTable::Allocate( | 15143 HashTable<Shape, Key>::Allocate( |
15190 heap, | 15144 heap, |
15191 at_least_space_for, | 15145 at_least_space_for, |
15192 USE_DEFAULT_MINIMUM_CAPACITY, | 15146 USE_DEFAULT_MINIMUM_CAPACITY, |
15193 pretenure); | 15147 pretenure); |
15194 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15148 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15195 } | 15149 } |
15196 // Initialize the next enumeration index. | 15150 // Initialize the next enumeration index. |
15197 Dictionary::cast(obj)-> | 15151 Dictionary<Shape, Key>::cast(obj)-> |
15198 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15152 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
15199 return obj; | 15153 return obj; |
15200 } | 15154 } |
15201 | 15155 |
15202 | 15156 |
15203 void NameDictionary::DoGenerateNewEnumerationIndices( | 15157 void NameDictionary::DoGenerateNewEnumerationIndices( |
15204 Handle<NameDictionary> dictionary) { | 15158 Handle<NameDictionary> dictionary) { |
15205 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 15159 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
15206 dictionary->GenerateNewEnumerationIndices()); | 15160 dictionary->GenerateNewEnumerationIndices()); |
15207 } | 15161 } |
15208 | 15162 |
15209 template<typename Derived, typename Shape, typename Key> | 15163 template<typename Shape, typename Key> |
15210 MaybeObject* Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices() { | 15164 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
15211 Heap* heap = Dictionary::GetHeap(); | 15165 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
15212 int length = DerivedHashTable::NumberOfElements(); | 15166 int length = HashTable<Shape, Key>::NumberOfElements(); |
15213 | 15167 |
15214 // Allocate and initialize iteration order array. | 15168 // Allocate and initialize iteration order array. |
15215 Object* obj; | 15169 Object* obj; |
15216 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15170 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
15217 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15171 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15218 } | 15172 } |
15219 FixedArray* iteration_order = FixedArray::cast(obj); | 15173 FixedArray* iteration_order = FixedArray::cast(obj); |
15220 for (int i = 0; i < length; i++) { | 15174 for (int i = 0; i < length; i++) { |
15221 iteration_order->set(i, Smi::FromInt(i)); | 15175 iteration_order->set(i, Smi::FromInt(i)); |
15222 } | 15176 } |
15223 | 15177 |
15224 // Allocate array with enumeration order. | 15178 // Allocate array with enumeration order. |
15225 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15179 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
15226 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15180 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15227 } | 15181 } |
15228 FixedArray* enumeration_order = FixedArray::cast(obj); | 15182 FixedArray* enumeration_order = FixedArray::cast(obj); |
15229 | 15183 |
15230 // Fill the enumeration order array with property details. | 15184 // Fill the enumeration order array with property details. |
15231 int capacity = DerivedHashTable::Capacity(); | 15185 int capacity = HashTable<Shape, Key>::Capacity(); |
15232 int pos = 0; | 15186 int pos = 0; |
15233 for (int i = 0; i < capacity; i++) { | 15187 for (int i = 0; i < capacity; i++) { |
15234 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { | 15188 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
15235 int index = DetailsAt(i).dictionary_index(); | 15189 int index = DetailsAt(i).dictionary_index(); |
15236 enumeration_order->set(pos++, Smi::FromInt(index)); | 15190 enumeration_order->set(pos++, Smi::FromInt(index)); |
15237 } | 15191 } |
15238 } | 15192 } |
15239 | 15193 |
15240 // Sort the arrays wrt. enumeration order. | 15194 // Sort the arrays wrt. enumeration order. |
15241 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); | 15195 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); |
15242 | 15196 |
15243 // Overwrite the enumeration_order with the enumeration indices. | 15197 // Overwrite the enumeration_order with the enumeration indices. |
15244 for (int i = 0; i < length; i++) { | 15198 for (int i = 0; i < length; i++) { |
15245 int index = Smi::cast(iteration_order->get(i))->value(); | 15199 int index = Smi::cast(iteration_order->get(i))->value(); |
15246 int enum_index = PropertyDetails::kInitialIndex + i; | 15200 int enum_index = PropertyDetails::kInitialIndex + i; |
15247 enumeration_order->set(index, Smi::FromInt(enum_index)); | 15201 enumeration_order->set(index, Smi::FromInt(enum_index)); |
15248 } | 15202 } |
15249 | 15203 |
15250 // Update the dictionary with new indices. | 15204 // Update the dictionary with new indices. |
15251 capacity = DerivedHashTable::Capacity(); | 15205 capacity = HashTable<Shape, Key>::Capacity(); |
15252 pos = 0; | 15206 pos = 0; |
15253 for (int i = 0; i < capacity; i++) { | 15207 for (int i = 0; i < capacity; i++) { |
15254 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { | 15208 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
15255 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 15209 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
15256 PropertyDetails details = DetailsAt(i); | 15210 PropertyDetails details = DetailsAt(i); |
15257 PropertyDetails new_details = PropertyDetails( | 15211 PropertyDetails new_details = PropertyDetails( |
15258 details.attributes(), details.type(), enum_index); | 15212 details.attributes(), details.type(), enum_index); |
15259 DetailsAtPut(i, new_details); | 15213 DetailsAtPut(i, new_details); |
15260 } | 15214 } |
15261 } | 15215 } |
15262 | 15216 |
15263 // Set the next enumeration index. | 15217 // Set the next enumeration index. |
15264 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 15218 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
15265 return this; | 15219 return this; |
15266 } | 15220 } |
15267 | 15221 |
15268 template<typename Derived, typename Shape, typename Key> | 15222 template<typename Shape, typename Key> |
15269 MaybeObject* Dictionary<Derived, Shape, Key>::EnsureCapacity(int n, Key key) { | 15223 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { |
15270 // Check whether there are enough enumeration indices to add n elements. | 15224 // Check whether there are enough enumeration indices to add n elements. |
15271 if (Shape::kIsEnumerable && | 15225 if (Shape::kIsEnumerable && |
15272 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 15226 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
15273 // If not, we generate new indices for the properties. | 15227 // If not, we generate new indices for the properties. |
15274 Object* result; | 15228 Object* result; |
15275 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15229 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
15276 if (!maybe_result->ToObject(&result)) return maybe_result; | 15230 if (!maybe_result->ToObject(&result)) return maybe_result; |
15277 } | 15231 } |
15278 } | 15232 } |
15279 return DerivedHashTable::EnsureCapacity(n, key); | 15233 return HashTable<Shape, Key>::EnsureCapacity(n, key); |
15280 } | 15234 } |
15281 | 15235 |
15282 | 15236 |
15283 // TODO(ishell): Temporary wrapper until handlified. | 15237 // TODO(ishell): Temporary wrapper until handlified. |
15284 template<typename Derived, typename Shape, typename Key> | 15238 template<typename Shape, typename Key> |
15285 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( | 15239 Handle<Object> Dictionary<Shape, Key>::DeleteProperty( |
15286 Handle<Dictionary<Derived, Shape, Key> > dictionary, | 15240 Handle<Dictionary<Shape, Key> > dictionary, |
15287 int entry, | 15241 int entry, |
15288 JSObject::DeleteMode mode) { | 15242 JSObject::DeleteMode mode) { |
15289 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15243 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
15290 dictionary->DeleteProperty(entry, mode), | 15244 dictionary->DeleteProperty(entry, mode), |
15291 Object); | 15245 Object); |
15292 } | 15246 } |
15293 | 15247 |
15294 | 15248 |
15295 template<typename Derived, typename Shape, typename Key> | 15249 template<typename Shape, typename Key> |
15296 Object* Dictionary<Derived, Shape, Key>::DeleteProperty( | 15250 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, |
15297 int entry, | 15251 JSReceiver::DeleteMode mode) { |
15298 JSReceiver::DeleteMode mode) { | 15252 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
15299 Heap* heap = Dictionary::GetHeap(); | |
15300 PropertyDetails details = DetailsAt(entry); | 15253 PropertyDetails details = DetailsAt(entry); |
15301 // Ignore attributes if forcing a deletion. | 15254 // Ignore attributes if forcing a deletion. |
15302 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 15255 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
15303 return heap->false_value(); | 15256 return heap->false_value(); |
15304 } | 15257 } |
15305 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); | 15258 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
15306 DerivedHashTable::ElementRemoved(); | 15259 HashTable<Shape, Key>::ElementRemoved(); |
15307 return heap->true_value(); | 15260 return heap->true_value(); |
15308 } | 15261 } |
15309 | 15262 |
15310 | 15263 |
15311 template<typename Derived, typename Shape, typename Key> | 15264 // TODO(ishell): Temporary wrapper until handlified. |
15312 MaybeObject* Dictionary<Derived, Shape, Key>::AtPut(Key key, Object* value) { | 15265 template<typename Shape, typename Key> |
| 15266 Handle<FixedArray> Dictionary<Shape, Key>::Shrink( |
| 15267 Handle<Dictionary<Shape, Key> > dictionary, |
| 15268 Key key) { |
| 15269 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15270 dictionary->Shrink(key), |
| 15271 FixedArray); |
| 15272 } |
| 15273 |
| 15274 |
| 15275 template<typename Shape, typename Key> |
| 15276 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { |
| 15277 return HashTable<Shape, Key>::Shrink(key); |
| 15278 } |
| 15279 |
| 15280 |
| 15281 template<typename Shape, typename Key> |
| 15282 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { |
15313 int entry = this->FindEntry(key); | 15283 int entry = this->FindEntry(key); |
15314 | 15284 |
15315 // If the entry is present set the value; | 15285 // If the entry is present set the value; |
15316 if (entry != Dictionary::kNotFound) { | 15286 if (entry != Dictionary<Shape, Key>::kNotFound) { |
15317 ValueAtPut(entry, value); | 15287 ValueAtPut(entry, value); |
15318 return this; | 15288 return this; |
15319 } | 15289 } |
15320 | 15290 |
15321 // Check whether the dictionary should be extended. | 15291 // Check whether the dictionary should be extended. |
15322 Object* obj; | 15292 Object* obj; |
15323 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15293 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
15324 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15294 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15325 } | 15295 } |
15326 | 15296 |
15327 Object* k; | 15297 Object* k; |
15328 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15298 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
15329 if (!maybe_k->ToObject(&k)) return maybe_k; | 15299 if (!maybe_k->ToObject(&k)) return maybe_k; |
15330 } | 15300 } |
15331 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); | 15301 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); |
15332 | 15302 |
15333 return Dictionary::cast(obj)->AddEntry( | 15303 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
15334 key, value, details, Dictionary::Hash(key)); | 15304 Dictionary<Shape, Key>::Hash(key)); |
15335 } | 15305 } |
15336 | 15306 |
15337 | 15307 |
15338 template<typename Derived, typename Shape, typename Key> | 15308 template<typename Shape, typename Key> |
15339 MaybeObject* Dictionary<Derived, Shape, Key>::Add( | 15309 MaybeObject* Dictionary<Shape, Key>::Add(Key key, |
15340 Key key, | 15310 Object* value, |
15341 Object* value, | 15311 PropertyDetails details) { |
15342 PropertyDetails details) { | |
15343 // Valdate key is absent. | 15312 // Valdate key is absent. |
15344 SLOW_ASSERT((this->FindEntry(key) == Dictionary::kNotFound)); | 15313 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); |
15345 // Check whether the dictionary should be extended. | 15314 // Check whether the dictionary should be extended. |
15346 Object* obj; | 15315 Object* obj; |
15347 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15316 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
15348 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15317 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15349 } | 15318 } |
15350 | 15319 |
15351 return Dictionary::cast(obj)->AddEntry( | 15320 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
15352 key, value, details, Dictionary::Hash(key)); | 15321 Dictionary<Shape, Key>::Hash(key)); |
15353 } | 15322 } |
15354 | 15323 |
15355 | 15324 |
15356 // Add a key, value pair to the dictionary. | 15325 // Add a key, value pair to the dictionary. |
15357 template<typename Derived, typename Shape, typename Key> | 15326 template<typename Shape, typename Key> |
15358 MaybeObject* Dictionary<Derived, Shape, Key>::AddEntry( | 15327 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, |
15359 Key key, | 15328 Object* value, |
15360 Object* value, | 15329 PropertyDetails details, |
15361 PropertyDetails details, | 15330 uint32_t hash) { |
15362 uint32_t hash) { | |
15363 // Compute the key object. | 15331 // Compute the key object. |
15364 Object* k; | 15332 Object* k; |
15365 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15333 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
15366 if (!maybe_k->ToObject(&k)) return maybe_k; | 15334 if (!maybe_k->ToObject(&k)) return maybe_k; |
15367 } | 15335 } |
15368 | 15336 |
15369 uint32_t entry = Dictionary::FindInsertionEntry(hash); | 15337 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); |
15370 // Insert element at empty or deleted entry | 15338 // Insert element at empty or deleted entry |
15371 if (!details.IsDeleted() && | 15339 if (!details.IsDeleted() && |
15372 details.dictionary_index() == 0 && | 15340 details.dictionary_index() == 0 && |
15373 Shape::kIsEnumerable) { | 15341 Shape::kIsEnumerable) { |
15374 // Assign an enumeration index to the property and update | 15342 // Assign an enumeration index to the property and update |
15375 // SetNextEnumerationIndex. | 15343 // SetNextEnumerationIndex. |
15376 int index = NextEnumerationIndex(); | 15344 int index = NextEnumerationIndex(); |
15377 details = PropertyDetails(details.attributes(), details.type(), index); | 15345 details = PropertyDetails(details.attributes(), details.type(), index); |
15378 SetNextEnumerationIndex(index + 1); | 15346 SetNextEnumerationIndex(index + 1); |
15379 } | 15347 } |
15380 SetEntry(entry, k, value, details); | 15348 SetEntry(entry, k, value, details); |
15381 ASSERT((Dictionary::KeyAt(entry)->IsNumber() || | 15349 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || |
15382 Dictionary::KeyAt(entry)->IsName())); | 15350 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); |
15383 DerivedHashTable::ElementAdded(); | 15351 HashTable<Shape, Key>::ElementAdded(); |
15384 return this; | 15352 return this; |
15385 } | 15353 } |
15386 | 15354 |
15387 | 15355 |
15388 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15356 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
15389 // If the dictionary requires slow elements an element has already | 15357 // If the dictionary requires slow elements an element has already |
15390 // been added at a high index. | 15358 // been added at a high index. |
15391 if (requires_slow_elements()) return; | 15359 if (requires_slow_elements()) return; |
15392 // Check if this index is high enough that we should require slow | 15360 // Check if this index is high enough that we should require slow |
15393 // elements. | 15361 // elements. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15487 MaybeObject* maybe_object_key = | 15455 MaybeObject* maybe_object_key = |
15488 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); | 15456 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); |
15489 Object* object_key; | 15457 Object* object_key; |
15490 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 15458 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
15491 SetEntry(entry, object_key, value); | 15459 SetEntry(entry, object_key, value); |
15492 return this; | 15460 return this; |
15493 } | 15461 } |
15494 | 15462 |
15495 | 15463 |
15496 | 15464 |
15497 template<typename Derived, typename Shape, typename Key> | 15465 template<typename Shape, typename Key> |
15498 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( | 15466 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
15499 PropertyAttributes filter) { | 15467 PropertyAttributes filter) { |
15500 int capacity = DerivedHashTable::Capacity(); | 15468 int capacity = HashTable<Shape, Key>::Capacity(); |
15501 int result = 0; | 15469 int result = 0; |
15502 for (int i = 0; i < capacity; i++) { | 15470 for (int i = 0; i < capacity; i++) { |
15503 Object* k = DerivedHashTable::KeyAt(i); | 15471 Object* k = HashTable<Shape, Key>::KeyAt(i); |
15504 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 15472 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { |
15505 PropertyDetails details = DetailsAt(i); | 15473 PropertyDetails details = DetailsAt(i); |
15506 if (details.IsDeleted()) continue; | 15474 if (details.IsDeleted()) continue; |
15507 PropertyAttributes attr = details.attributes(); | 15475 PropertyAttributes attr = details.attributes(); |
15508 if ((attr & filter) == 0) result++; | 15476 if ((attr & filter) == 0) result++; |
15509 } | 15477 } |
15510 } | 15478 } |
15511 return result; | 15479 return result; |
15512 } | 15480 } |
15513 | 15481 |
15514 | 15482 |
15515 template<typename Derived, typename Shape, typename Key> | 15483 template<typename Shape, typename Key> |
15516 int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { | 15484 int Dictionary<Shape, Key>::NumberOfEnumElements() { |
15517 return NumberOfElementsFilterAttributes( | 15485 return NumberOfElementsFilterAttributes( |
15518 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15486 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
15519 } | 15487 } |
15520 | 15488 |
15521 | 15489 |
15522 template<typename Derived, typename Shape, typename Key> | 15490 template<typename Shape, typename Key> |
15523 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 15491 void Dictionary<Shape, Key>::CopyKeysTo( |
15524 FixedArray* storage, | 15492 FixedArray* storage, |
15525 PropertyAttributes filter, | 15493 PropertyAttributes filter, |
15526 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 15494 typename Dictionary<Shape, Key>::SortMode sort_mode) { |
15527 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15495 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15528 int capacity = DerivedHashTable::Capacity(); | 15496 int capacity = HashTable<Shape, Key>::Capacity(); |
15529 int index = 0; | 15497 int index = 0; |
15530 for (int i = 0; i < capacity; i++) { | 15498 for (int i = 0; i < capacity; i++) { |
15531 Object* k = DerivedHashTable::KeyAt(i); | 15499 Object* k = HashTable<Shape, Key>::KeyAt(i); |
15532 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 15500 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { |
15533 PropertyDetails details = DetailsAt(i); | 15501 PropertyDetails details = DetailsAt(i); |
15534 if (details.IsDeleted()) continue; | 15502 if (details.IsDeleted()) continue; |
15535 PropertyAttributes attr = details.attributes(); | 15503 PropertyAttributes attr = details.attributes(); |
15536 if ((attr & filter) == 0) storage->set(index++, k); | 15504 if ((attr & filter) == 0) storage->set(index++, k); |
15537 } | 15505 } |
15538 } | 15506 } |
15539 if (sort_mode == Dictionary::SORTED) { | 15507 if (sort_mode == Dictionary<Shape, Key>::SORTED) { |
15540 storage->SortPairs(storage, index); | 15508 storage->SortPairs(storage, index); |
15541 } | 15509 } |
15542 ASSERT(storage->length() >= index); | 15510 ASSERT(storage->length() >= index); |
15543 } | 15511 } |
15544 | 15512 |
15545 | 15513 |
15546 struct EnumIndexComparator { | 15514 struct EnumIndexComparator { |
15547 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15515 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
15548 bool operator() (Smi* a, Smi* b) { | 15516 bool operator() (Smi* a, Smi* b) { |
15549 PropertyDetails da(dict->DetailsAt(a->value())); | 15517 PropertyDetails da(dict->DetailsAt(a->value())); |
(...skipping 21 matching lines...) Expand all Loading... |
15571 EnumIndexComparator cmp(this); | 15539 EnumIndexComparator cmp(this); |
15572 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 15540 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
15573 std::sort(start, start + length, cmp); | 15541 std::sort(start, start + length, cmp); |
15574 for (int i = 0; i < length; i++) { | 15542 for (int i = 0; i < length; i++) { |
15575 int index = Smi::cast(storage->get(i))->value(); | 15543 int index = Smi::cast(storage->get(i))->value(); |
15576 storage->set(i, KeyAt(index)); | 15544 storage->set(i, KeyAt(index)); |
15577 } | 15545 } |
15578 } | 15546 } |
15579 | 15547 |
15580 | 15548 |
15581 template<typename Derived, typename Shape, typename Key> | 15549 template<typename Shape, typename Key> |
15582 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 15550 void Dictionary<Shape, Key>::CopyKeysTo( |
15583 FixedArray* storage, | 15551 FixedArray* storage, |
15584 int index, | 15552 int index, |
15585 PropertyAttributes filter, | 15553 PropertyAttributes filter, |
15586 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 15554 typename Dictionary<Shape, Key>::SortMode sort_mode) { |
15587 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15555 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15588 int capacity = DerivedHashTable::Capacity(); | 15556 int capacity = HashTable<Shape, Key>::Capacity(); |
15589 for (int i = 0; i < capacity; i++) { | 15557 for (int i = 0; i < capacity; i++) { |
15590 Object* k = DerivedHashTable::KeyAt(i); | 15558 Object* k = HashTable<Shape, Key>::KeyAt(i); |
15591 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 15559 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { |
15592 PropertyDetails details = DetailsAt(i); | 15560 PropertyDetails details = DetailsAt(i); |
15593 if (details.IsDeleted()) continue; | 15561 if (details.IsDeleted()) continue; |
15594 PropertyAttributes attr = details.attributes(); | 15562 PropertyAttributes attr = details.attributes(); |
15595 if ((attr & filter) == 0) storage->set(index++, k); | 15563 if ((attr & filter) == 0) storage->set(index++, k); |
15596 } | 15564 } |
15597 } | 15565 } |
15598 if (sort_mode == Dictionary::SORTED) { | 15566 if (sort_mode == Dictionary<Shape, Key>::SORTED) { |
15599 storage->SortPairs(storage, index); | 15567 storage->SortPairs(storage, index); |
15600 } | 15568 } |
15601 ASSERT(storage->length() >= index); | 15569 ASSERT(storage->length() >= index); |
15602 } | 15570 } |
15603 | 15571 |
15604 | 15572 |
15605 // Backwards lookup (slow). | 15573 // Backwards lookup (slow). |
15606 template<typename Derived, typename Shape, typename Key> | 15574 template<typename Shape, typename Key> |
15607 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 15575 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
15608 int capacity = DerivedHashTable::Capacity(); | 15576 int capacity = HashTable<Shape, Key>::Capacity(); |
15609 for (int i = 0; i < capacity; i++) { | 15577 for (int i = 0; i < capacity; i++) { |
15610 Object* k = DerivedHashTable::KeyAt(i); | 15578 Object* k = HashTable<Shape, Key>::KeyAt(i); |
15611 if (Dictionary::IsKey(k)) { | 15579 if (Dictionary<Shape, Key>::IsKey(k)) { |
15612 Object* e = ValueAt(i); | 15580 Object* e = ValueAt(i); |
15613 if (e->IsPropertyCell()) { | 15581 if (e->IsPropertyCell()) { |
15614 e = PropertyCell::cast(e)->value(); | 15582 e = PropertyCell::cast(e)->value(); |
15615 } | 15583 } |
15616 if (e == value) return k; | 15584 if (e == value) return k; |
15617 } | 15585 } |
15618 } | 15586 } |
15619 Heap* heap = Dictionary::GetHeap(); | 15587 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
15620 return heap->undefined_value(); | 15588 return heap->undefined_value(); |
15621 } | 15589 } |
15622 | 15590 |
15623 | 15591 |
15624 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15592 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
15625 Handle<ObjectHashTable> table, | 15593 Handle<ObjectHashTable> table, |
15626 int n, | 15594 int n, |
15627 Handle<Object> key, | 15595 Handle<Object> key, |
15628 PretenureFlag pretenure) { | 15596 PretenureFlag pretenure) { |
15629 Handle<HashTable<ObjectHashTable, | 15597 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; |
15630 ObjectHashTableShape, | |
15631 Object*> > table_base = table; | |
15632 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15598 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
15633 table_base->EnsureCapacity(n, *key, pretenure), | 15599 table_base->EnsureCapacity(n, *key, pretenure), |
15634 ObjectHashTable); | 15600 ObjectHashTable); |
15635 } | 15601 } |
15636 | 15602 |
15637 | 15603 |
| 15604 Handle<ObjectHashTable> ObjectHashTable::Shrink( |
| 15605 Handle<ObjectHashTable> table, Handle<Object> key) { |
| 15606 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; |
| 15607 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| 15608 table_base->Shrink(*key), |
| 15609 ObjectHashTable); |
| 15610 } |
| 15611 |
| 15612 |
15638 Object* ObjectHashTable::Lookup(Object* key) { | 15613 Object* ObjectHashTable::Lookup(Object* key) { |
15639 ASSERT(IsKey(key)); | 15614 ASSERT(IsKey(key)); |
15640 | 15615 |
15641 // If the object does not have an identity hash, it was never used as a key. | 15616 // If the object does not have an identity hash, it was never used as a key. |
15642 Object* hash = key->GetHash(); | 15617 Object* hash = key->GetHash(); |
15643 if (hash->IsUndefined()) { | 15618 if (hash->IsUndefined()) { |
15644 return GetHeap()->the_hole_value(); | 15619 return GetHeap()->the_hole_value(); |
15645 } | 15620 } |
15646 int entry = FindEntry(key); | 15621 int entry = FindEntry(key); |
15647 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15622 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16507 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16482 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16508 static const char* error_messages_[] = { | 16483 static const char* error_messages_[] = { |
16509 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16484 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16510 }; | 16485 }; |
16511 #undef ERROR_MESSAGES_TEXTS | 16486 #undef ERROR_MESSAGES_TEXTS |
16512 return error_messages_[reason]; | 16487 return error_messages_[reason]; |
16513 } | 16488 } |
16514 | 16489 |
16515 | 16490 |
16516 } } // namespace v8::internal | 16491 } } // namespace v8::internal |
OLD | NEW |