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