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 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 702 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
703 PropertyCell::SetValueInferType(cell, value); | 703 PropertyCell::SetValueInferType(cell, value); |
704 // Please note we have to update the property details. | 704 // Please note we have to update the property details. |
705 property_dictionary->DetailsAtPut(entry, details); | 705 property_dictionary->DetailsAtPut(entry, details); |
706 } else { | 706 } else { |
707 property_dictionary->SetEntry(entry, *name, *value, details); | 707 property_dictionary->SetEntry(entry, *name, *value, details); |
708 } | 708 } |
709 } | 709 } |
710 | 710 |
711 | 711 |
712 // TODO(mstarzinger): Temporary wrapper until target is handlified. | |
713 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, | |
714 Handle<Name> name) { | |
715 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); | |
716 } | |
717 | |
718 | |
719 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 712 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
720 Handle<Name> name, | 713 Handle<Name> name, |
721 DeleteMode mode) { | 714 DeleteMode mode) { |
722 ASSERT(!object->HasFastProperties()); | 715 ASSERT(!object->HasFastProperties()); |
723 Isolate* isolate = object->GetIsolate(); | 716 Isolate* isolate = object->GetIsolate(); |
724 Handle<NameDictionary> dictionary(object->property_dictionary()); | 717 Handle<NameDictionary> dictionary(object->property_dictionary()); |
725 int entry = dictionary->FindEntry(*name); | 718 int entry = dictionary->FindEntry(*name); |
726 if (entry != NameDictionary::kNotFound) { | 719 if (entry != NameDictionary::kNotFound) { |
727 // If we have a global object set the cell to the hole. | 720 // If we have a global object set the cell to the hole. |
728 if (object->IsGlobalObject()) { | 721 if (object->IsGlobalObject()) { |
729 PropertyDetails details = dictionary->DetailsAt(entry); | 722 PropertyDetails details = dictionary->DetailsAt(entry); |
730 if (details.IsDontDelete()) { | 723 if (details.IsDontDelete()) { |
731 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 724 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
732 // When forced to delete global properties, we have to make a | 725 // When forced to delete global properties, we have to make a |
733 // map change to invalidate any ICs that think they can load | 726 // map change to invalidate any ICs that think they can load |
734 // from the DontDelete cell without checking if it contains | 727 // from the DontDelete cell without checking if it contains |
735 // the hole value. | 728 // the hole value. |
736 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 729 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
737 ASSERT(new_map->is_dictionary_map()); | 730 ASSERT(new_map->is_dictionary_map()); |
738 object->set_map(*new_map); | 731 object->set_map(*new_map); |
739 } | 732 } |
740 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 733 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
741 Handle<Object> value = isolate->factory()->the_hole_value(); | 734 Handle<Object> value = isolate->factory()->the_hole_value(); |
742 PropertyCell::SetValueInferType(cell, value); | 735 PropertyCell::SetValueInferType(cell, value); |
743 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 736 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
744 } else { | 737 } else { |
745 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); | 738 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
746 if (*deleted == isolate->heap()->true_value()) { | 739 if (*deleted == isolate->heap()->true_value()) { |
747 Handle<NameDictionary> new_properties = | 740 Handle<NameDictionary> new_properties = |
748 NameDictionaryShrink(dictionary, name); | 741 NameDictionary::Shrink(dictionary, *name); |
749 object->set_properties(*new_properties); | 742 object->set_properties(*new_properties); |
750 } | 743 } |
751 return deleted; | 744 return deleted; |
752 } | 745 } |
753 } | 746 } |
754 return isolate->factory()->true_value(); | 747 return isolate->factory()->true_value(); |
755 } | 748 } |
756 | 749 |
757 | 750 |
758 bool JSObject::IsDirty() { | 751 bool JSObject::IsDirty() { |
(...skipping 12282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13041 } | 13034 } |
13042 } | 13035 } |
13043 | 13036 |
13044 | 13037 |
13045 // Certain compilers request function template instantiation when they | 13038 // Certain compilers request function template instantiation when they |
13046 // see the definition of the other template functions in the | 13039 // see the definition of the other template functions in the |
13047 // class. This requires us to have the template functions put | 13040 // class. This requires us to have the template functions put |
13048 // together, so even though this function belongs in objects-debug.cc, | 13041 // together, so even though this function belongs in objects-debug.cc, |
13049 // we keep it here instead to satisfy certain compilers. | 13042 // we keep it here instead to satisfy certain compilers. |
13050 #ifdef OBJECT_PRINT | 13043 #ifdef OBJECT_PRINT |
13051 template<typename Shape, typename Key> | 13044 template<typename Derived, typename Shape, typename Key> |
13052 void Dictionary<Shape, Key>::Print(FILE* out) { | 13045 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { |
13053 int capacity = HashTable<Shape, Key>::Capacity(); | 13046 int capacity = HashTable_::Capacity(); |
13054 for (int i = 0; i < capacity; i++) { | 13047 for (int i = 0; i < capacity; i++) { |
13055 Object* k = HashTable<Shape, Key>::KeyAt(i); | 13048 Object* k = HashTable_::KeyAt(i); |
13056 if (HashTable<Shape, Key>::IsKey(k)) { | 13049 if (HashTable_::IsKey(k)) { |
13057 PrintF(out, " "); | 13050 PrintF(out, " "); |
13058 if (k->IsString()) { | 13051 if (k->IsString()) { |
13059 String::cast(k)->StringPrint(out); | 13052 String::cast(k)->StringPrint(out); |
13060 } else { | 13053 } else { |
13061 k->ShortPrint(out); | 13054 k->ShortPrint(out); |
13062 } | 13055 } |
13063 PrintF(out, ": "); | 13056 PrintF(out, ": "); |
13064 ValueAt(i)->ShortPrint(out); | 13057 ValueAt(i)->ShortPrint(out); |
13065 PrintF(out, "\n"); | 13058 PrintF(out, "\n"); |
13066 } | 13059 } |
13067 } | 13060 } |
13068 } | 13061 } |
13069 #endif | 13062 #endif |
13070 | 13063 |
13071 | 13064 |
13072 template<typename Shape, typename Key> | 13065 template<typename Derived, typename Shape, typename Key> |
13073 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13066 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
13074 int pos = 0; | 13067 int pos = 0; |
13075 int capacity = HashTable<Shape, Key>::Capacity(); | 13068 int capacity = HashTable_::Capacity(); |
13076 DisallowHeapAllocation no_gc; | 13069 DisallowHeapAllocation no_gc; |
13077 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13070 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
13078 for (int i = 0; i < capacity; i++) { | 13071 for (int i = 0; i < capacity; i++) { |
13079 Object* k = Dictionary<Shape, Key>::KeyAt(i); | 13072 Object* k = Dictionary::KeyAt(i); |
13080 if (Dictionary<Shape, Key>::IsKey(k)) { | 13073 if (Dictionary::IsKey(k)) { |
13081 elements->set(pos++, ValueAt(i), mode); | 13074 elements->set(pos++, ValueAt(i), mode); |
13082 } | 13075 } |
13083 } | 13076 } |
13084 ASSERT(pos == elements->length()); | 13077 ASSERT(pos == elements->length()); |
13085 } | 13078 } |
13086 | 13079 |
13087 | 13080 |
13088 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13081 InterceptorInfo* JSObject::GetNamedInterceptor() { |
13089 ASSERT(map()->has_named_interceptor()); | 13082 ASSERT(map()->has_named_interceptor()); |
13090 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13083 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13774 } | 13767 } |
13775 | 13768 |
13776 static uint32_t StringHash(Object* obj) { | 13769 static uint32_t StringHash(Object* obj) { |
13777 return String::cast(obj)->Hash(); | 13770 return String::cast(obj)->Hash(); |
13778 } | 13771 } |
13779 | 13772 |
13780 String* string_; | 13773 String* string_; |
13781 }; | 13774 }; |
13782 | 13775 |
13783 | 13776 |
13784 template<typename Shape, typename Key> | 13777 template<typename Derived, typename Shape, typename Key> |
13785 void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { | 13778 void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
13786 IteratePointers(v, 0, kElementsStartOffset); | 13779 IteratePointers(v, 0, kElementsStartOffset); |
13787 } | 13780 } |
13788 | 13781 |
13789 | 13782 |
13790 template<typename Shape, typename Key> | 13783 template<typename Derived, typename Shape, typename Key> |
13791 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 13784 void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) { |
13792 IteratePointers(v, | 13785 IteratePointers(v, |
13793 kElementsStartOffset, | 13786 kElementsStartOffset, |
13794 kHeaderSize + length() * kPointerSize); | 13787 kHeaderSize + length() * kPointerSize); |
13795 } | 13788 } |
13796 | 13789 |
13797 | 13790 |
13798 template<typename Shape, typename Key> | 13791 template<typename Derived, typename Shape, typename Key> |
13799 MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap, | 13792 MaybeObject* HashTable<Derived, Shape, Key>::Allocate( |
13800 int at_least_space_for, | 13793 Heap* heap, |
13801 MinimumCapacity capacity_option, | 13794 int at_least_space_for, |
13802 PretenureFlag pretenure) { | 13795 MinimumCapacity capacity_option, |
| 13796 PretenureFlag pretenure) { |
13803 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 13797 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); |
13804 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 13798 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
13805 ? at_least_space_for | 13799 ? at_least_space_for |
13806 : ComputeCapacity(at_least_space_for); | 13800 : ComputeCapacity(at_least_space_for); |
13807 if (capacity > HashTable::kMaxCapacity) { | 13801 if (capacity > HashTable::kMaxCapacity) { |
13808 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 13802 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
13809 } | 13803 } |
13810 | 13804 |
13811 Object* obj; | 13805 Object* obj; |
13812 { MaybeObject* maybe_obj = | 13806 { MaybeObject* maybe_obj = |
13813 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); | 13807 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); |
13814 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13808 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
13815 } | 13809 } |
13816 HashTable::cast(obj)->SetNumberOfElements(0); | 13810 HashTable::cast(obj)->SetNumberOfElements(0); |
13817 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 13811 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
13818 HashTable::cast(obj)->SetCapacity(capacity); | 13812 HashTable::cast(obj)->SetCapacity(capacity); |
13819 return obj; | 13813 return obj; |
13820 } | 13814 } |
13821 | 13815 |
13822 | 13816 |
| 13817 template<typename Derived, typename Shape, typename Key> |
| 13818 Handle<Derived> HashTable<Derived, Shape, Key>::New( |
| 13819 Isolate* isolate, |
| 13820 int at_least_space_for, |
| 13821 MinimumCapacity capacity_option, |
| 13822 PretenureFlag pretenure) { |
| 13823 CALL_HEAP_FUNCTION( |
| 13824 isolate, |
| 13825 Allocate(isolate->heap(), at_least_space_for, capacity_option, pretenure), |
| 13826 Derived); |
| 13827 } |
| 13828 |
| 13829 |
13823 // Find entry for key otherwise return kNotFound. | 13830 // Find entry for key otherwise return kNotFound. |
13824 int NameDictionary::FindEntry(Name* key) { | 13831 int NameDictionary::FindEntry(Name* key) { |
13825 if (!key->IsUniqueName()) { | 13832 if (!key->IsUniqueName()) { |
13826 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); | 13833 return HashTable_::FindEntry(key); |
13827 } | 13834 } |
13828 | 13835 |
13829 // Optimized for unique names. Knowledge of the key type allows: | 13836 // Optimized for unique names. Knowledge of the key type allows: |
13830 // 1. Move the check if the key is unique out of the loop. | 13837 // 1. Move the check if the key is unique out of the loop. |
13831 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 13838 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
13832 // 3. Detect a case when a dictionary key is not unique but the key is. | 13839 // 3. Detect a case when a dictionary key is not unique but the key is. |
13833 // In case of positive result the dictionary key may be replaced by the | 13840 // In case of positive result the dictionary key may be replaced by the |
13834 // internalized string with minimal performance penalty. It gives a chance | 13841 // internalized string with minimal performance penalty. It gives a chance |
13835 // to perform further lookups in code stubs (and significant performance | 13842 // to perform further lookups in code stubs (and significant performance |
13836 // boost a certain style of code). | 13843 // boost a certain style of code). |
(...skipping 16 matching lines...) Expand all Loading... |
13853 set(index, key); | 13860 set(index, key); |
13854 return entry; | 13861 return entry; |
13855 } | 13862 } |
13856 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); | 13863 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
13857 entry = NextProbe(entry, count++, capacity); | 13864 entry = NextProbe(entry, count++, capacity); |
13858 } | 13865 } |
13859 return kNotFound; | 13866 return kNotFound; |
13860 } | 13867 } |
13861 | 13868 |
13862 | 13869 |
13863 template<typename Shape, typename Key> | 13870 template<typename Derived, typename Shape, typename Key> |
13864 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 13871 void HashTable<Derived, Shape, Key>::Rehash(Derived* new_table, Key key) { |
13865 ASSERT(NumberOfElements() < new_table->Capacity()); | 13872 ASSERT(NumberOfElements() < new_table->Capacity()); |
13866 | 13873 |
13867 DisallowHeapAllocation no_gc; | 13874 DisallowHeapAllocation no_gc; |
13868 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 13875 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
13869 | 13876 |
13870 // Copy prefix to new array. | 13877 // Copy prefix to new array. |
13871 for (int i = kPrefixStartIndex; | 13878 for (int i = kPrefixStartIndex; |
13872 i < kPrefixStartIndex + Shape::kPrefixSize; | 13879 i < kPrefixStartIndex + Shape::kPrefixSize; |
13873 i++) { | 13880 i++) { |
13874 new_table->set(i, get(i), mode); | 13881 new_table->set(i, get(i), mode); |
13875 } | 13882 } |
13876 | 13883 |
13877 // Rehash the elements. | 13884 // Rehash the elements. |
13878 int capacity = Capacity(); | 13885 int capacity = Capacity(); |
13879 for (int i = 0; i < capacity; i++) { | 13886 for (int i = 0; i < capacity; i++) { |
13880 uint32_t from_index = EntryToIndex(i); | 13887 uint32_t from_index = EntryToIndex(i); |
13881 Object* k = get(from_index); | 13888 Object* k = get(from_index); |
13882 if (IsKey(k)) { | 13889 if (IsKey(k)) { |
13883 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 13890 uint32_t hash = HashTable::HashForObject(key, k); |
13884 uint32_t insertion_index = | 13891 uint32_t insertion_index = |
13885 EntryToIndex(new_table->FindInsertionEntry(hash)); | 13892 EntryToIndex(new_table->FindInsertionEntry(hash)); |
13886 for (int j = 0; j < Shape::kEntrySize; j++) { | 13893 for (int j = 0; j < Shape::kEntrySize; j++) { |
13887 new_table->set(insertion_index + j, get(from_index + j), mode); | 13894 new_table->set(insertion_index + j, get(from_index + j), mode); |
13888 } | 13895 } |
13889 } | 13896 } |
13890 } | 13897 } |
13891 new_table->SetNumberOfElements(NumberOfElements()); | 13898 new_table->SetNumberOfElements(NumberOfElements()); |
13892 new_table->SetNumberOfDeletedElements(0); | 13899 new_table->SetNumberOfDeletedElements(0); |
13893 return new_table; | |
13894 } | 13900 } |
13895 | 13901 |
13896 | 13902 |
13897 template<typename Shape, typename Key> | 13903 template<typename Derived, typename Shape, typename Key> |
13898 uint32_t HashTable<Shape, Key>::EntryForProbe(Key key, | 13904 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( |
13899 Object* k, | 13905 Key key, |
13900 int probe, | 13906 Object* k, |
13901 uint32_t expected) { | 13907 int probe, |
13902 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 13908 uint32_t expected) { |
| 13909 uint32_t hash = HashTable::HashForObject(key, k); |
13903 uint32_t capacity = Capacity(); | 13910 uint32_t capacity = Capacity(); |
13904 uint32_t entry = FirstProbe(hash, capacity); | 13911 uint32_t entry = FirstProbe(hash, capacity); |
13905 for (int i = 1; i < probe; i++) { | 13912 for (int i = 1; i < probe; i++) { |
13906 if (entry == expected) return expected; | 13913 if (entry == expected) return expected; |
13907 entry = NextProbe(entry, i, capacity); | 13914 entry = NextProbe(entry, i, capacity); |
13908 } | 13915 } |
13909 return entry; | 13916 return entry; |
13910 } | 13917 } |
13911 | 13918 |
13912 | 13919 |
13913 template<typename Shape, typename Key> | 13920 template<typename Derived, typename Shape, typename Key> |
13914 void HashTable<Shape, Key>::Swap(uint32_t entry1, | 13921 void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1, |
13915 uint32_t entry2, | 13922 uint32_t entry2, |
13916 WriteBarrierMode mode) { | 13923 WriteBarrierMode mode) { |
13917 int index1 = EntryToIndex(entry1); | 13924 int index1 = EntryToIndex(entry1); |
13918 int index2 = EntryToIndex(entry2); | 13925 int index2 = EntryToIndex(entry2); |
13919 Object* temp[Shape::kEntrySize]; | 13926 Object* temp[Shape::kEntrySize]; |
13920 for (int j = 0; j < Shape::kEntrySize; j++) { | 13927 for (int j = 0; j < Shape::kEntrySize; j++) { |
13921 temp[j] = get(index1 + j); | 13928 temp[j] = get(index1 + j); |
13922 } | 13929 } |
13923 for (int j = 0; j < Shape::kEntrySize; j++) { | 13930 for (int j = 0; j < Shape::kEntrySize; j++) { |
13924 set(index1 + j, get(index2 + j), mode); | 13931 set(index1 + j, get(index2 + j), mode); |
13925 } | 13932 } |
13926 for (int j = 0; j < Shape::kEntrySize; j++) { | 13933 for (int j = 0; j < Shape::kEntrySize; j++) { |
13927 set(index2 + j, temp[j], mode); | 13934 set(index2 + j, temp[j], mode); |
13928 } | 13935 } |
13929 } | 13936 } |
13930 | 13937 |
13931 | 13938 |
13932 template<typename Shape, typename Key> | 13939 template<typename Derived, typename Shape, typename Key> |
13933 void HashTable<Shape, Key>::Rehash(Key key) { | 13940 void HashTable<Derived, Shape, Key>::Rehash(Key key) { |
13934 DisallowHeapAllocation no_gc; | 13941 DisallowHeapAllocation no_gc; |
13935 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 13942 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
13936 uint32_t capacity = Capacity(); | 13943 uint32_t capacity = Capacity(); |
13937 bool done = false; | 13944 bool done = false; |
13938 for (int probe = 1; !done; probe++) { | 13945 for (int probe = 1; !done; probe++) { |
13939 // All elements at entries given by one of the first _probe_ probes | 13946 // All elements at entries given by one of the first _probe_ probes |
13940 // are placed correctly. Other elements might need to be moved. | 13947 // are placed correctly. Other elements might need to be moved. |
13941 done = true; | 13948 done = true; |
13942 for (uint32_t current = 0; current < capacity; current++) { | 13949 for (uint32_t current = 0; current < capacity; current++) { |
13943 Object* current_key = get(EntryToIndex(current)); | 13950 Object* current_key = get(EntryToIndex(current)); |
(...skipping 11 matching lines...) Expand all Loading... |
13955 // The place for the current element is occupied. Leave the element | 13962 // The place for the current element is occupied. Leave the element |
13956 // for the next probe. | 13963 // for the next probe. |
13957 done = false; | 13964 done = false; |
13958 } | 13965 } |
13959 } | 13966 } |
13960 } | 13967 } |
13961 } | 13968 } |
13962 } | 13969 } |
13963 | 13970 |
13964 | 13971 |
13965 template<typename Shape, typename Key> | 13972 template<typename Derived, typename Shape, typename Key> |
13966 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, | 13973 MaybeObject* HashTable<Derived, Shape, Key>::EnsureCapacity( |
13967 Key key, | 13974 int n, |
13968 PretenureFlag pretenure) { | 13975 Key key, |
| 13976 PretenureFlag pretenure) { |
13969 int capacity = Capacity(); | 13977 int capacity = Capacity(); |
13970 int nof = NumberOfElements() + n; | 13978 int nof = NumberOfElements() + n; |
13971 int nod = NumberOfDeletedElements(); | 13979 int nod = NumberOfDeletedElements(); |
13972 // Return if: | 13980 // Return if: |
13973 // 50% is still free after adding n elements and | 13981 // 50% is still free after adding n elements and |
13974 // at most 50% of the free elements are deleted elements. | 13982 // at most 50% of the free elements are deleted elements. |
13975 if (nod <= (capacity - nof) >> 1) { | 13983 if (nod <= (capacity - nof) >> 1) { |
13976 int needed_free = nof >> 1; | 13984 int needed_free = nof >> 1; |
13977 if (nof + needed_free <= capacity) return this; | 13985 if (nof + needed_free <= capacity) return this; |
13978 } | 13986 } |
13979 | 13987 |
13980 const int kMinCapacityForPretenure = 256; | 13988 const int kMinCapacityForPretenure = 256; |
13981 bool should_pretenure = pretenure == TENURED || | 13989 bool should_pretenure = pretenure == TENURED || |
13982 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); | 13990 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
13983 Object* obj; | 13991 Object* obj; |
13984 { MaybeObject* maybe_obj = | 13992 { MaybeObject* maybe_obj = |
13985 Allocate(GetHeap(), | 13993 Allocate(GetHeap(), |
13986 nof * 2, | 13994 nof * 2, |
13987 USE_DEFAULT_MINIMUM_CAPACITY, | 13995 USE_DEFAULT_MINIMUM_CAPACITY, |
13988 should_pretenure ? TENURED : NOT_TENURED); | 13996 should_pretenure ? TENURED : NOT_TENURED); |
13989 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13997 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
13990 } | 13998 } |
13991 | 13999 |
13992 return Rehash(HashTable::cast(obj), key); | 14000 Rehash(Derived::cast(obj), key); |
| 14001 return Derived::cast(obj); |
13993 } | 14002 } |
13994 | 14003 |
13995 | 14004 |
13996 template<typename Shape, typename Key> | 14005 template<typename Derived, typename Shape, typename Key> |
13997 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 14006 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, |
13998 int capacity = Capacity(); | 14007 Key key) { |
13999 int nof = NumberOfElements(); | 14008 int capacity = table->Capacity(); |
| 14009 int nof = table->NumberOfElements(); |
14000 | 14010 |
14001 // Shrink to fit the number of elements if only a quarter of the | 14011 // Shrink to fit the number of elements if only a quarter of the |
14002 // capacity is filled with elements. | 14012 // capacity is filled with elements. |
14003 if (nof > (capacity >> 2)) return this; | 14013 if (nof > (capacity >> 2)) return table; |
14004 // Allocate a new dictionary with room for at least the current | 14014 // Allocate a new dictionary with room for at least the current |
14005 // number of elements. The allocation method will make sure that | 14015 // number of elements. The allocation method will make sure that |
14006 // there is extra room in the dictionary for additions. Don't go | 14016 // there is extra room in the dictionary for additions. Don't go |
14007 // lower than room for 16 elements. | 14017 // lower than room for 16 elements. |
14008 int at_least_room_for = nof; | 14018 int at_least_room_for = nof; |
14009 if (at_least_room_for < 16) return this; | 14019 if (at_least_room_for < 16) return table; |
14010 | 14020 |
| 14021 Isolate* isolate = table->GetIsolate(); |
14011 const int kMinCapacityForPretenure = 256; | 14022 const int kMinCapacityForPretenure = 256; |
14012 bool pretenure = | 14023 bool pretenure = |
14013 (at_least_room_for > kMinCapacityForPretenure) && | 14024 (at_least_room_for > kMinCapacityForPretenure) && |
14014 !GetHeap()->InNewSpace(this); | 14025 !isolate->heap()->InNewSpace(*table); |
14015 Object* obj; | 14026 Handle<Derived> new_table = New( |
14016 { MaybeObject* maybe_obj = | 14027 isolate, |
14017 Allocate(GetHeap(), | 14028 at_least_room_for, |
14018 at_least_room_for, | 14029 USE_DEFAULT_MINIMUM_CAPACITY, |
14019 USE_DEFAULT_MINIMUM_CAPACITY, | 14030 pretenure ? TENURED : NOT_TENURED); |
14020 pretenure ? TENURED : NOT_TENURED); | |
14021 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
14022 } | |
14023 | 14031 |
14024 return Rehash(HashTable::cast(obj), key); | 14032 table->Rehash(*new_table, key); |
| 14033 return new_table; |
14025 } | 14034 } |
14026 | 14035 |
14027 | 14036 |
14028 template<typename Shape, typename Key> | 14037 template<typename Derived, typename Shape, typename Key> |
14029 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 14038 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { |
14030 uint32_t capacity = Capacity(); | 14039 uint32_t capacity = Capacity(); |
14031 uint32_t entry = FirstProbe(hash, capacity); | 14040 uint32_t entry = FirstProbe(hash, capacity); |
14032 uint32_t count = 1; | 14041 uint32_t count = 1; |
14033 // EnsureCapacity will guarantee the hash table is never full. | 14042 // EnsureCapacity will guarantee the hash table is never full. |
14034 while (true) { | 14043 while (true) { |
14035 Object* element = KeyAt(entry); | 14044 Object* element = KeyAt(entry); |
14036 if (element->IsUndefined() || element->IsTheHole()) break; | 14045 if (element->IsUndefined() || element->IsTheHole()) break; |
14037 entry = NextProbe(entry, count++, capacity); | 14046 entry = NextProbe(entry, count++, capacity); |
14038 } | 14047 } |
14039 return entry; | 14048 return entry; |
14040 } | 14049 } |
14041 | 14050 |
14042 | 14051 |
14043 // Force instantiation of template instances class. | 14052 // Force instantiation of template instances class. |
14044 // Please note this list is compiler dependent. | 14053 // Please note this list is compiler dependent. |
14045 | 14054 |
14046 template class HashTable<StringTableShape, HashTableKey*>; | 14055 template class HashTable<StringTable, StringTableShape, HashTableKey*>; |
14047 | 14056 |
14048 template class HashTable<CompilationCacheShape, HashTableKey*>; | 14057 template class HashTable<CompilationCacheTable, |
| 14058 CompilationCacheShape, |
| 14059 HashTableKey*>; |
14049 | 14060 |
14050 template class HashTable<MapCacheShape, HashTableKey*>; | 14061 template class HashTable<MapCache, MapCacheShape, HashTableKey*>; |
14051 | 14062 |
14052 template class HashTable<ObjectHashTableShape, Object*>; | 14063 template class HashTable<ObjectHashTable, ObjectHashTableShape, Object*>; |
14053 | 14064 |
14054 template class HashTable<WeakHashTableShape<2>, Object*>; | 14065 template class HashTable<WeakHashTable, WeakHashTableShape<2>, Object*>; |
14055 | 14066 |
14056 template class Dictionary<NameDictionaryShape, Name*>; | 14067 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; |
14057 | 14068 |
14058 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 14069 template class Dictionary<SeededNumberDictionary, |
| 14070 SeededNumberDictionaryShape, |
| 14071 uint32_t>; |
14059 | 14072 |
14060 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 14073 template class Dictionary<UnseededNumberDictionary, |
| 14074 UnseededNumberDictionaryShape, |
| 14075 uint32_t>; |
14061 | 14076 |
14062 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14077 template MaybeObject* |
| 14078 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14063 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14079 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
14064 | 14080 |
14065 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14081 template MaybeObject* |
| 14082 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
14066 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14083 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
14067 | 14084 |
14068 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14085 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
14069 Allocate(Heap* heap, int n, PretenureFlag pretenure); | 14086 Allocate(Heap* heap, int n, PretenureFlag pretenure); |
14070 | 14087 |
14071 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( | 14088 template MaybeObject* |
14072 uint32_t, Object*); | 14089 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14073 | |
14074 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | |
14075 AtPut(uint32_t, Object*); | 14090 AtPut(uint32_t, Object*); |
14076 | 14091 |
14077 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14092 template MaybeObject* |
| 14093 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14094 AtPut(uint32_t, Object*); |
| 14095 |
| 14096 template Object* |
| 14097 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14078 SlowReverseLookup(Object* value); | 14098 SlowReverseLookup(Object* value); |
14079 | 14099 |
14080 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14100 template Object* |
| 14101 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
14081 SlowReverseLookup(Object* value); | 14102 SlowReverseLookup(Object* value); |
14082 | 14103 |
14083 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( | 14104 template Object* |
| 14105 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SlowReverseLookup( |
14084 Object*); | 14106 Object*); |
14085 | 14107 |
14086 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( | 14108 template void |
14087 FixedArray*, | 14109 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14088 PropertyAttributes, | 14110 CopyKeysTo( |
14089 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); | 14111 FixedArray*, |
| 14112 PropertyAttributes, |
| 14113 Dictionary<SeededNumberDictionary, |
| 14114 SeededNumberDictionaryShape, |
| 14115 uint32_t>::SortMode); |
14090 | 14116 |
14091 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14117 template Object* |
| 14118 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
14092 int, JSObject::DeleteMode); | 14119 int, JSObject::DeleteMode); |
14093 | 14120 |
14094 template Handle<Object> Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14121 template Handle<Object> |
14095 Handle<Dictionary<NameDictionaryShape, Name*> >, | 14122 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14123 Handle<Dictionary<NameDictionary, NameDictionaryShape, Name*> >, |
14096 int, | 14124 int, |
14097 JSObject::DeleteMode); | 14125 JSObject::DeleteMode); |
14098 | 14126 |
14099 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14127 template Object* |
| 14128 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14100 DeleteProperty(int, JSObject::DeleteMode); | 14129 DeleteProperty(int, JSObject::DeleteMode); |
14101 | 14130 |
14102 template Handle<Object> | 14131 template Handle<Object> |
14103 Dictionary<SeededNumberDictionaryShape, uint32_t>::DeleteProperty( | 14132 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14104 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | 14133 DeleteProperty( |
14105 int, | 14134 Handle<Dictionary<SeededNumberDictionary, |
14106 JSObject::DeleteMode); | 14135 SeededNumberDictionaryShape, |
| 14136 uint32_t> >, |
| 14137 int, |
| 14138 JSObject::DeleteMode); |
14107 | 14139 |
14108 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); | 14140 template void Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
14109 | 14141 CopyKeysTo( |
14110 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14142 FixedArray*, |
14111 uint32_t); | 14143 int, |
14112 template Handle<FixedArray> | 14144 PropertyAttributes, |
14113 Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14145 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SortMode); |
14114 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | |
14115 uint32_t); | |
14116 | |
14117 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( | |
14118 FixedArray*, | |
14119 int, | |
14120 PropertyAttributes, | |
14121 Dictionary<NameDictionaryShape, Name*>::SortMode); | |
14122 | 14146 |
14123 template int | 14147 template int |
14124 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( | 14148 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
14125 PropertyAttributes); | 14149 NumberOfElementsFilterAttributes(PropertyAttributes); |
14126 | 14150 |
14127 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( | 14151 template MaybeObject* |
| 14152 Dictionary<NameDictionary, NameDictionaryShape, Name*>::Add( |
14128 Name*, Object*, PropertyDetails); | 14153 Name*, Object*, PropertyDetails); |
14129 | 14154 |
14130 template MaybeObject* | 14155 template MaybeObject* |
14131 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); | 14156 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14157 GenerateNewEnumerationIndices(); |
14132 | 14158 |
14133 template int | 14159 template int |
14134 Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14160 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14135 NumberOfElementsFilterAttributes(PropertyAttributes); | 14161 NumberOfElementsFilterAttributes(PropertyAttributes); |
14136 | 14162 |
14137 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( | 14163 template MaybeObject* |
| 14164 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add( |
14138 uint32_t, Object*, PropertyDetails); | 14165 uint32_t, Object*, PropertyDetails); |
14139 | 14166 |
14140 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( | 14167 template MaybeObject* |
14141 uint32_t, Object*, PropertyDetails); | 14168 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14169 Add(uint32_t, Object*, PropertyDetails); |
14142 | 14170 |
14143 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14171 template MaybeObject* |
| 14172 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14144 EnsureCapacity(int, uint32_t); | 14173 EnsureCapacity(int, uint32_t); |
14145 | 14174 |
14146 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14175 template MaybeObject* |
| 14176 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
14147 EnsureCapacity(int, uint32_t); | 14177 EnsureCapacity(int, uint32_t); |
14148 | 14178 |
14149 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14179 template MaybeObject* |
| 14180 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
14150 EnsureCapacity(int, Name*); | 14181 EnsureCapacity(int, Name*); |
14151 | 14182 |
14152 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14183 template MaybeObject* |
| 14184 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14153 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14185 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
14154 | 14186 |
14155 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14187 template MaybeObject* |
| 14188 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
14156 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14189 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
14157 | 14190 |
14158 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( | 14191 template MaybeObject* |
| 14192 Dictionary<NameDictionary, NameDictionaryShape, Name*>::AddEntry( |
14159 Name*, Object*, PropertyDetails, uint32_t); | 14193 Name*, Object*, PropertyDetails, uint32_t); |
14160 | 14194 |
14161 template | 14195 template |
14162 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 14196 int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14197 NumberOfEnumElements(); |
14163 | 14198 |
14164 template | 14199 template |
14165 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); | 14200 int Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14201 NumberOfEnumElements(); |
14166 | 14202 |
14167 template | 14203 template |
14168 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 14204 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14205 FindEntry(uint32_t); |
14169 | 14206 |
14170 | 14207 |
14171 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14208 Handle<Object> JSObject::PrepareSlowElementsForSort( |
14172 Handle<JSObject> object, uint32_t limit) { | 14209 Handle<JSObject> object, uint32_t limit) { |
14173 CALL_HEAP_FUNCTION(object->GetIsolate(), | 14210 CALL_HEAP_FUNCTION(object->GetIsolate(), |
14174 object->PrepareSlowElementsForSort(limit), | 14211 object->PrepareSlowElementsForSort(limit), |
14175 Object); | 14212 Object); |
14176 } | 14213 } |
14177 | 14214 |
14178 | 14215 |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15004 | 15041 |
15005 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15042 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
15006 int entry = cache->FindInsertionEntry(key.Hash()); | 15043 int entry = cache->FindInsertionEntry(key.Hash()); |
15007 cache->set(EntryToIndex(entry), array); | 15044 cache->set(EntryToIndex(entry), array); |
15008 cache->set(EntryToIndex(entry) + 1, value); | 15045 cache->set(EntryToIndex(entry) + 1, value); |
15009 cache->ElementAdded(); | 15046 cache->ElementAdded(); |
15010 return cache; | 15047 return cache; |
15011 } | 15048 } |
15012 | 15049 |
15013 | 15050 |
15014 template<typename Shape, typename Key> | 15051 template<typename Derived, typename Shape, typename Key> |
15015 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, | 15052 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( |
15016 int at_least_space_for, | 15053 Heap* heap, |
15017 PretenureFlag pretenure) { | 15054 int at_least_space_for, |
| 15055 PretenureFlag pretenure) { |
15018 Object* obj; | 15056 Object* obj; |
15019 { MaybeObject* maybe_obj = | 15057 { MaybeObject* maybe_obj = |
15020 HashTable<Shape, Key>::Allocate( | 15058 HashTable_::Allocate( |
15021 heap, | 15059 heap, |
15022 at_least_space_for, | 15060 at_least_space_for, |
15023 USE_DEFAULT_MINIMUM_CAPACITY, | 15061 USE_DEFAULT_MINIMUM_CAPACITY, |
15024 pretenure); | 15062 pretenure); |
15025 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15063 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15026 } | 15064 } |
15027 // Initialize the next enumeration index. | 15065 // Initialize the next enumeration index. |
15028 Dictionary<Shape, Key>::cast(obj)-> | 15066 Dictionary::cast(obj)-> |
15029 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15067 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
15030 return obj; | 15068 return obj; |
15031 } | 15069 } |
15032 | 15070 |
15033 | 15071 |
15034 void NameDictionary::DoGenerateNewEnumerationIndices( | 15072 void NameDictionary::DoGenerateNewEnumerationIndices( |
15035 Handle<NameDictionary> dictionary) { | 15073 Handle<NameDictionary> dictionary) { |
15036 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 15074 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
15037 dictionary->GenerateNewEnumerationIndices()); | 15075 dictionary->GenerateNewEnumerationIndices()); |
15038 } | 15076 } |
15039 | 15077 |
15040 template<typename Shape, typename Key> | 15078 template<typename Derived, typename Shape, typename Key> |
15041 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 15079 MaybeObject* Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices() { |
15042 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15080 Heap* heap = Dictionary::GetHeap(); |
15043 int length = HashTable<Shape, Key>::NumberOfElements(); | 15081 int length = HashTable_::NumberOfElements(); |
15044 | 15082 |
15045 // Allocate and initialize iteration order array. | 15083 // Allocate and initialize iteration order array. |
15046 Object* obj; | 15084 Object* obj; |
15047 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15085 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
15048 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15086 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15049 } | 15087 } |
15050 FixedArray* iteration_order = FixedArray::cast(obj); | 15088 FixedArray* iteration_order = FixedArray::cast(obj); |
15051 for (int i = 0; i < length; i++) { | 15089 for (int i = 0; i < length; i++) { |
15052 iteration_order->set(i, Smi::FromInt(i)); | 15090 iteration_order->set(i, Smi::FromInt(i)); |
15053 } | 15091 } |
15054 | 15092 |
15055 // Allocate array with enumeration order. | 15093 // Allocate array with enumeration order. |
15056 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15094 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
15057 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15095 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15058 } | 15096 } |
15059 FixedArray* enumeration_order = FixedArray::cast(obj); | 15097 FixedArray* enumeration_order = FixedArray::cast(obj); |
15060 | 15098 |
15061 // Fill the enumeration order array with property details. | 15099 // Fill the enumeration order array with property details. |
15062 int capacity = HashTable<Shape, Key>::Capacity(); | 15100 int capacity = HashTable_::Capacity(); |
15063 int pos = 0; | 15101 int pos = 0; |
15064 for (int i = 0; i < capacity; i++) { | 15102 for (int i = 0; i < capacity; i++) { |
15065 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15103 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
15066 int index = DetailsAt(i).dictionary_index(); | 15104 int index = DetailsAt(i).dictionary_index(); |
15067 enumeration_order->set(pos++, Smi::FromInt(index)); | 15105 enumeration_order->set(pos++, Smi::FromInt(index)); |
15068 } | 15106 } |
15069 } | 15107 } |
15070 | 15108 |
15071 // Sort the arrays wrt. enumeration order. | 15109 // Sort the arrays wrt. enumeration order. |
15072 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); | 15110 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); |
15073 | 15111 |
15074 // Overwrite the enumeration_order with the enumeration indices. | 15112 // Overwrite the enumeration_order with the enumeration indices. |
15075 for (int i = 0; i < length; i++) { | 15113 for (int i = 0; i < length; i++) { |
15076 int index = Smi::cast(iteration_order->get(i))->value(); | 15114 int index = Smi::cast(iteration_order->get(i))->value(); |
15077 int enum_index = PropertyDetails::kInitialIndex + i; | 15115 int enum_index = PropertyDetails::kInitialIndex + i; |
15078 enumeration_order->set(index, Smi::FromInt(enum_index)); | 15116 enumeration_order->set(index, Smi::FromInt(enum_index)); |
15079 } | 15117 } |
15080 | 15118 |
15081 // Update the dictionary with new indices. | 15119 // Update the dictionary with new indices. |
15082 capacity = HashTable<Shape, Key>::Capacity(); | 15120 capacity = HashTable_::Capacity(); |
15083 pos = 0; | 15121 pos = 0; |
15084 for (int i = 0; i < capacity; i++) { | 15122 for (int i = 0; i < capacity; i++) { |
15085 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15123 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
15086 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 15124 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
15087 PropertyDetails details = DetailsAt(i); | 15125 PropertyDetails details = DetailsAt(i); |
15088 PropertyDetails new_details = PropertyDetails( | 15126 PropertyDetails new_details = PropertyDetails( |
15089 details.attributes(), details.type(), enum_index); | 15127 details.attributes(), details.type(), enum_index); |
15090 DetailsAtPut(i, new_details); | 15128 DetailsAtPut(i, new_details); |
15091 } | 15129 } |
15092 } | 15130 } |
15093 | 15131 |
15094 // Set the next enumeration index. | 15132 // Set the next enumeration index. |
15095 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 15133 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
15096 return this; | 15134 return this; |
15097 } | 15135 } |
15098 | 15136 |
15099 template<typename Shape, typename Key> | 15137 template<typename Derived, typename Shape, typename Key> |
15100 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { | 15138 MaybeObject* Dictionary<Derived, Shape, Key>::EnsureCapacity(int n, Key key) { |
15101 // Check whether there are enough enumeration indices to add n elements. | 15139 // Check whether there are enough enumeration indices to add n elements. |
15102 if (Shape::kIsEnumerable && | 15140 if (Shape::kIsEnumerable && |
15103 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 15141 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
15104 // If not, we generate new indices for the properties. | 15142 // If not, we generate new indices for the properties. |
15105 Object* result; | 15143 Object* result; |
15106 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15144 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
15107 if (!maybe_result->ToObject(&result)) return maybe_result; | 15145 if (!maybe_result->ToObject(&result)) return maybe_result; |
15108 } | 15146 } |
15109 } | 15147 } |
15110 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 15148 return HashTable_::EnsureCapacity(n, key); |
15111 } | 15149 } |
15112 | 15150 |
15113 | 15151 |
15114 // TODO(ishell): Temporary wrapper until handlified. | 15152 // TODO(ishell): Temporary wrapper until handlified. |
15115 template<typename Shape, typename Key> | 15153 template<typename Derived, typename Shape, typename Key> |
15116 Handle<Object> Dictionary<Shape, Key>::DeleteProperty( | 15154 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
15117 Handle<Dictionary<Shape, Key> > dictionary, | 15155 Handle<Dictionary<Derived, Shape, Key> > dictionary, |
15118 int entry, | 15156 int entry, |
15119 JSObject::DeleteMode mode) { | 15157 JSObject::DeleteMode mode) { |
15120 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15158 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
15121 dictionary->DeleteProperty(entry, mode), | 15159 dictionary->DeleteProperty(entry, mode), |
15122 Object); | 15160 Object); |
15123 } | 15161 } |
15124 | 15162 |
15125 | 15163 |
15126 template<typename Shape, typename Key> | 15164 template<typename Derived, typename Shape, typename Key> |
15127 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 15165 Object* Dictionary<Derived, Shape, Key>::DeleteProperty( |
15128 JSReceiver::DeleteMode mode) { | 15166 int entry, |
15129 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15167 JSReceiver::DeleteMode mode) { |
| 15168 Heap* heap = Dictionary::GetHeap(); |
15130 PropertyDetails details = DetailsAt(entry); | 15169 PropertyDetails details = DetailsAt(entry); |
15131 // Ignore attributes if forcing a deletion. | 15170 // Ignore attributes if forcing a deletion. |
15132 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 15171 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
15133 return heap->false_value(); | 15172 return heap->false_value(); |
15134 } | 15173 } |
15135 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); | 15174 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
15136 HashTable<Shape, Key>::ElementRemoved(); | 15175 HashTable_::ElementRemoved(); |
15137 return heap->true_value(); | 15176 return heap->true_value(); |
15138 } | 15177 } |
15139 | 15178 |
15140 | 15179 |
15141 // TODO(ishell): Temporary wrapper until handlified. | 15180 template<typename Derived, typename Shape, typename Key> |
15142 template<typename Shape, typename Key> | 15181 MaybeObject* Dictionary<Derived, Shape, Key>::AtPut(Key key, Object* value) { |
15143 Handle<FixedArray> Dictionary<Shape, Key>::Shrink( | |
15144 Handle<Dictionary<Shape, Key> > dictionary, | |
15145 Key key) { | |
15146 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | |
15147 dictionary->Shrink(key), | |
15148 FixedArray); | |
15149 } | |
15150 | |
15151 | |
15152 template<typename Shape, typename Key> | |
15153 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { | |
15154 return HashTable<Shape, Key>::Shrink(key); | |
15155 } | |
15156 | |
15157 | |
15158 template<typename Shape, typename Key> | |
15159 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | |
15160 int entry = this->FindEntry(key); | 15182 int entry = this->FindEntry(key); |
15161 | 15183 |
15162 // If the entry is present set the value; | 15184 // If the entry is present set the value; |
15163 if (entry != Dictionary<Shape, Key>::kNotFound) { | 15185 if (entry != Dictionary::kNotFound) { |
15164 ValueAtPut(entry, value); | 15186 ValueAtPut(entry, value); |
15165 return this; | 15187 return this; |
15166 } | 15188 } |
15167 | 15189 |
15168 // Check whether the dictionary should be extended. | 15190 // Check whether the dictionary should be extended. |
15169 Object* obj; | 15191 Object* obj; |
15170 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15192 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
15171 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15193 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15172 } | 15194 } |
15173 | 15195 |
15174 Object* k; | 15196 Object* k; |
15175 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15197 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
15176 if (!maybe_k->ToObject(&k)) return maybe_k; | 15198 if (!maybe_k->ToObject(&k)) return maybe_k; |
15177 } | 15199 } |
15178 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); | 15200 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); |
15179 | 15201 |
15180 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15202 return Dictionary::cast(obj)->AddEntry( |
15181 Dictionary<Shape, Key>::Hash(key)); | 15203 key, value, details, Dictionary::Hash(key)); |
15182 } | 15204 } |
15183 | 15205 |
15184 | 15206 |
15185 template<typename Shape, typename Key> | 15207 template<typename Derived, typename Shape, typename Key> |
15186 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 15208 MaybeObject* Dictionary<Derived, Shape, Key>::Add( |
15187 Object* value, | 15209 Key key, |
15188 PropertyDetails details) { | 15210 Object* value, |
| 15211 PropertyDetails details) { |
15189 // Valdate key is absent. | 15212 // Valdate key is absent. |
15190 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 15213 SLOW_ASSERT((this->FindEntry(key) == Dictionary::kNotFound)); |
15191 // Check whether the dictionary should be extended. | 15214 // Check whether the dictionary should be extended. |
15192 Object* obj; | 15215 Object* obj; |
15193 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15216 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
15194 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15217 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15195 } | 15218 } |
15196 | 15219 |
15197 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15220 return Dictionary::cast(obj)->AddEntry( |
15198 Dictionary<Shape, Key>::Hash(key)); | 15221 key, value, details, Dictionary::Hash(key)); |
15199 } | 15222 } |
15200 | 15223 |
15201 | 15224 |
15202 // Add a key, value pair to the dictionary. | 15225 // Add a key, value pair to the dictionary. |
15203 template<typename Shape, typename Key> | 15226 template<typename Derived, typename Shape, typename Key> |
15204 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 15227 MaybeObject* Dictionary<Derived, Shape, Key>::AddEntry( |
15205 Object* value, | 15228 Key key, |
15206 PropertyDetails details, | 15229 Object* value, |
15207 uint32_t hash) { | 15230 PropertyDetails details, |
| 15231 uint32_t hash) { |
15208 // Compute the key object. | 15232 // Compute the key object. |
15209 Object* k; | 15233 Object* k; |
15210 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15234 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
15211 if (!maybe_k->ToObject(&k)) return maybe_k; | 15235 if (!maybe_k->ToObject(&k)) return maybe_k; |
15212 } | 15236 } |
15213 | 15237 |
15214 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 15238 uint32_t entry = Dictionary::FindInsertionEntry(hash); |
15215 // Insert element at empty or deleted entry | 15239 // Insert element at empty or deleted entry |
15216 if (!details.IsDeleted() && | 15240 if (!details.IsDeleted() && |
15217 details.dictionary_index() == 0 && | 15241 details.dictionary_index() == 0 && |
15218 Shape::kIsEnumerable) { | 15242 Shape::kIsEnumerable) { |
15219 // Assign an enumeration index to the property and update | 15243 // Assign an enumeration index to the property and update |
15220 // SetNextEnumerationIndex. | 15244 // SetNextEnumerationIndex. |
15221 int index = NextEnumerationIndex(); | 15245 int index = NextEnumerationIndex(); |
15222 details = PropertyDetails(details.attributes(), details.type(), index); | 15246 details = PropertyDetails(details.attributes(), details.type(), index); |
15223 SetNextEnumerationIndex(index + 1); | 15247 SetNextEnumerationIndex(index + 1); |
15224 } | 15248 } |
15225 SetEntry(entry, k, value, details); | 15249 SetEntry(entry, k, value, details); |
15226 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || | 15250 ASSERT((Dictionary::KeyAt(entry)->IsNumber() || |
15227 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); | 15251 Dictionary::KeyAt(entry)->IsName())); |
15228 HashTable<Shape, Key>::ElementAdded(); | 15252 HashTable_::ElementAdded(); |
15229 return this; | 15253 return this; |
15230 } | 15254 } |
15231 | 15255 |
15232 | 15256 |
15233 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15257 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
15234 // If the dictionary requires slow elements an element has already | 15258 // If the dictionary requires slow elements an element has already |
15235 // been added at a high index. | 15259 // been added at a high index. |
15236 if (requires_slow_elements()) return; | 15260 if (requires_slow_elements()) return; |
15237 // Check if this index is high enough that we should require slow | 15261 // Check if this index is high enough that we should require slow |
15238 // elements. | 15262 // elements. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15332 MaybeObject* maybe_object_key = | 15356 MaybeObject* maybe_object_key = |
15333 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); | 15357 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); |
15334 Object* object_key; | 15358 Object* object_key; |
15335 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 15359 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
15336 SetEntry(entry, object_key, value); | 15360 SetEntry(entry, object_key, value); |
15337 return this; | 15361 return this; |
15338 } | 15362 } |
15339 | 15363 |
15340 | 15364 |
15341 | 15365 |
15342 template<typename Shape, typename Key> | 15366 template<typename Derived, typename Shape, typename Key> |
15343 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 15367 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
15344 PropertyAttributes filter) { | 15368 PropertyAttributes filter) { |
15345 int capacity = HashTable<Shape, Key>::Capacity(); | 15369 int capacity = HashTable_::Capacity(); |
15346 int result = 0; | 15370 int result = 0; |
15347 for (int i = 0; i < capacity; i++) { | 15371 for (int i = 0; i < capacity; i++) { |
15348 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15372 Object* k = HashTable_::KeyAt(i); |
15349 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15373 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
15350 PropertyDetails details = DetailsAt(i); | 15374 PropertyDetails details = DetailsAt(i); |
15351 if (details.IsDeleted()) continue; | 15375 if (details.IsDeleted()) continue; |
15352 PropertyAttributes attr = details.attributes(); | 15376 PropertyAttributes attr = details.attributes(); |
15353 if ((attr & filter) == 0) result++; | 15377 if ((attr & filter) == 0) result++; |
15354 } | 15378 } |
15355 } | 15379 } |
15356 return result; | 15380 return result; |
15357 } | 15381 } |
15358 | 15382 |
15359 | 15383 |
15360 template<typename Shape, typename Key> | 15384 template<typename Derived, typename Shape, typename Key> |
15361 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 15385 int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { |
15362 return NumberOfElementsFilterAttributes( | 15386 return NumberOfElementsFilterAttributes( |
15363 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15387 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
15364 } | 15388 } |
15365 | 15389 |
15366 | 15390 |
15367 template<typename Shape, typename Key> | 15391 template<typename Derived, typename Shape, typename Key> |
15368 void Dictionary<Shape, Key>::CopyKeysTo( | 15392 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
15369 FixedArray* storage, | 15393 FixedArray* storage, |
15370 PropertyAttributes filter, | 15394 PropertyAttributes filter, |
15371 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15395 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
15372 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15396 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15373 int capacity = HashTable<Shape, Key>::Capacity(); | 15397 int capacity = HashTable_::Capacity(); |
15374 int index = 0; | 15398 int index = 0; |
15375 for (int i = 0; i < capacity; i++) { | 15399 for (int i = 0; i < capacity; i++) { |
15376 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15400 Object* k = HashTable_::KeyAt(i); |
15377 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15401 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
15378 PropertyDetails details = DetailsAt(i); | 15402 PropertyDetails details = DetailsAt(i); |
15379 if (details.IsDeleted()) continue; | 15403 if (details.IsDeleted()) continue; |
15380 PropertyAttributes attr = details.attributes(); | 15404 PropertyAttributes attr = details.attributes(); |
15381 if ((attr & filter) == 0) storage->set(index++, k); | 15405 if ((attr & filter) == 0) storage->set(index++, k); |
15382 } | 15406 } |
15383 } | 15407 } |
15384 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15408 if (sort_mode == Dictionary::SORTED) { |
15385 storage->SortPairs(storage, index); | 15409 storage->SortPairs(storage, index); |
15386 } | 15410 } |
15387 ASSERT(storage->length() >= index); | 15411 ASSERT(storage->length() >= index); |
15388 } | 15412 } |
15389 | 15413 |
15390 | 15414 |
15391 struct EnumIndexComparator { | 15415 struct EnumIndexComparator { |
15392 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15416 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
15393 bool operator() (Smi* a, Smi* b) { | 15417 bool operator() (Smi* a, Smi* b) { |
15394 PropertyDetails da(dict->DetailsAt(a->value())); | 15418 PropertyDetails da(dict->DetailsAt(a->value())); |
(...skipping 21 matching lines...) Expand all Loading... |
15416 EnumIndexComparator cmp(this); | 15440 EnumIndexComparator cmp(this); |
15417 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 15441 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
15418 std::sort(start, start + length, cmp); | 15442 std::sort(start, start + length, cmp); |
15419 for (int i = 0; i < length; i++) { | 15443 for (int i = 0; i < length; i++) { |
15420 int index = Smi::cast(storage->get(i))->value(); | 15444 int index = Smi::cast(storage->get(i))->value(); |
15421 storage->set(i, KeyAt(index)); | 15445 storage->set(i, KeyAt(index)); |
15422 } | 15446 } |
15423 } | 15447 } |
15424 | 15448 |
15425 | 15449 |
15426 template<typename Shape, typename Key> | 15450 template<typename Derived, typename Shape, typename Key> |
15427 void Dictionary<Shape, Key>::CopyKeysTo( | 15451 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
15428 FixedArray* storage, | 15452 FixedArray* storage, |
15429 int index, | 15453 int index, |
15430 PropertyAttributes filter, | 15454 PropertyAttributes filter, |
15431 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15455 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
15432 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15456 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15433 int capacity = HashTable<Shape, Key>::Capacity(); | 15457 int capacity = HashTable_::Capacity(); |
15434 for (int i = 0; i < capacity; i++) { | 15458 for (int i = 0; i < capacity; i++) { |
15435 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15459 Object* k = HashTable_::KeyAt(i); |
15436 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15460 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
15437 PropertyDetails details = DetailsAt(i); | 15461 PropertyDetails details = DetailsAt(i); |
15438 if (details.IsDeleted()) continue; | 15462 if (details.IsDeleted()) continue; |
15439 PropertyAttributes attr = details.attributes(); | 15463 PropertyAttributes attr = details.attributes(); |
15440 if ((attr & filter) == 0) storage->set(index++, k); | 15464 if ((attr & filter) == 0) storage->set(index++, k); |
15441 } | 15465 } |
15442 } | 15466 } |
15443 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15467 if (sort_mode == Dictionary::SORTED) { |
15444 storage->SortPairs(storage, index); | 15468 storage->SortPairs(storage, index); |
15445 } | 15469 } |
15446 ASSERT(storage->length() >= index); | 15470 ASSERT(storage->length() >= index); |
15447 } | 15471 } |
15448 | 15472 |
15449 | 15473 |
15450 // Backwards lookup (slow). | 15474 // Backwards lookup (slow). |
15451 template<typename Shape, typename Key> | 15475 template<typename Derived, typename Shape, typename Key> |
15452 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 15476 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
15453 int capacity = HashTable<Shape, Key>::Capacity(); | 15477 int capacity = HashTable_::Capacity(); |
15454 for (int i = 0; i < capacity; i++) { | 15478 for (int i = 0; i < capacity; i++) { |
15455 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15479 Object* k = HashTable_::KeyAt(i); |
15456 if (Dictionary<Shape, Key>::IsKey(k)) { | 15480 if (Dictionary::IsKey(k)) { |
15457 Object* e = ValueAt(i); | 15481 Object* e = ValueAt(i); |
15458 if (e->IsPropertyCell()) { | 15482 if (e->IsPropertyCell()) { |
15459 e = PropertyCell::cast(e)->value(); | 15483 e = PropertyCell::cast(e)->value(); |
15460 } | 15484 } |
15461 if (e == value) return k; | 15485 if (e == value) return k; |
15462 } | 15486 } |
15463 } | 15487 } |
15464 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15488 Heap* heap = Dictionary::GetHeap(); |
15465 return heap->undefined_value(); | 15489 return heap->undefined_value(); |
15466 } | 15490 } |
15467 | 15491 |
15468 | 15492 |
15469 MaybeObject* NameDictionary::TransformPropertiesToFastFor( | 15493 MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
15470 JSObject* obj, int unused_property_fields) { | 15494 JSObject* obj, int unused_property_fields) { |
15471 // Make sure we preserve dictionary representation if there are too many | 15495 // Make sure we preserve dictionary representation if there are too many |
15472 // descriptors. | 15496 // descriptors. |
15473 int number_of_elements = NumberOfElements(); | 15497 int number_of_elements = NumberOfElements(); |
15474 if (number_of_elements > kMaxNumberOfDescriptors) return obj; | 15498 if (number_of_elements > kMaxNumberOfDescriptors) return obj; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15609 | 15633 |
15610 return obj; | 15634 return obj; |
15611 } | 15635 } |
15612 | 15636 |
15613 | 15637 |
15614 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15638 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
15615 Handle<ObjectHashTable> table, | 15639 Handle<ObjectHashTable> table, |
15616 int n, | 15640 int n, |
15617 Handle<Object> key, | 15641 Handle<Object> key, |
15618 PretenureFlag pretenure) { | 15642 PretenureFlag pretenure) { |
15619 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | 15643 Handle<HashTable<ObjectHashTable, |
| 15644 ObjectHashTableShape, |
| 15645 Object*> > table_base = table; |
15620 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15646 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
15621 table_base->EnsureCapacity(n, *key, pretenure), | 15647 table_base->EnsureCapacity(n, *key, pretenure), |
15622 ObjectHashTable); | 15648 ObjectHashTable); |
15623 } | 15649 } |
15624 | 15650 |
15625 | 15651 |
15626 Handle<ObjectHashTable> ObjectHashTable::Shrink( | |
15627 Handle<ObjectHashTable> table, Handle<Object> key) { | |
15628 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | |
15629 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | |
15630 table_base->Shrink(*key), | |
15631 ObjectHashTable); | |
15632 } | |
15633 | |
15634 | |
15635 Object* ObjectHashTable::Lookup(Object* key) { | 15652 Object* ObjectHashTable::Lookup(Object* key) { |
15636 ASSERT(IsKey(key)); | 15653 ASSERT(IsKey(key)); |
15637 | 15654 |
15638 // If the object does not have an identity hash, it was never used as a key. | 15655 // If the object does not have an identity hash, it was never used as a key. |
15639 Object* hash = key->GetHash(); | 15656 Object* hash = key->GetHash(); |
15640 if (hash->IsUndefined()) { | 15657 if (hash->IsUndefined()) { |
15641 return GetHeap()->the_hole_value(); | 15658 return GetHeap()->the_hole_value(); |
15642 } | 15659 } |
15643 int entry = FindEntry(key); | 15660 int entry = FindEntry(key); |
15644 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15661 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16504 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16521 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16505 static const char* error_messages_[] = { | 16522 static const char* error_messages_[] = { |
16506 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16523 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16507 }; | 16524 }; |
16508 #undef ERROR_MESSAGES_TEXTS | 16525 #undef ERROR_MESSAGES_TEXTS |
16509 return error_messages_[reason]; | 16526 return error_messages_[reason]; |
16510 } | 16527 } |
16511 | 16528 |
16512 | 16529 |
16513 } } // namespace v8::internal | 16530 } } // namespace v8::internal |
OLD | NEW |